Merge pull request 'GraphQL Part1 (gql endpoint only) #162' (#192) from #162 into 1.0.0

Reviewed-on: sh-edraft.de/kd_discord_bot#192
Reviewed-by: edraft-dev <dev.sven.heidemann@sh-edraft.de>
This commit is contained in:
Sven Heidemann 2023-02-11 10:30:41 +01:00
commit 1d1fc8a876
76 changed files with 2034 additions and 57 deletions

View File

@ -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", [])

View File

@ -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",

View File

@ -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",

@ -1 +1 @@
Subproject commit 54b1b3860cb570d29c8ba2590dd082a1fa744265
Subproject commit b0ae87621bbe54fd9c5650071ec8c1c9ec32df48

View File

@ -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,

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -4,7 +4,6 @@ from werkzeug.exceptions import Unauthorized
class ServiceErrorCode(Enum):
Unknown = 0
InvalidDependencies = 1

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -2,6 +2,5 @@ from enum import Enum
class AuthRoleEnum(Enum):
normal = 0
admin = 1

View File

@ -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}'

View File

@ -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}'

View File

@ -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):

View File

@ -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(

View File

@ -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(

View File

@ -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

View File

@ -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],
)

View File

@ -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(

View File

@ -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(

View File

@ -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__,

View File

@ -0,0 +1 @@
# imports

View File

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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": []
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,6 @@
from bot_graphql.abc.query_abc import QueryABC
class GraphQLService:
def __init__(self, queries: list[QueryABC]):
self._queries = queries

View File

@ -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
}

View File

@ -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
}

View File

@ -0,0 +1,14 @@
interface TableQuery {
createdAt: String
modifiedAt: String
}
input Page {
pageIndex: Int
pageSize: Int
}
input Sort {
sortDirection: String
sortColumn: String
}

View File

@ -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
}

View File

@ -0,0 +1,7 @@
type KnownUser implements TableQuery {
id: ID
discordId: String
createdAt: String
modifiedAt: String
}

View File

@ -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
}

View File

@ -0,0 +1,6 @@
type Mutation {
autoRole: AutoRoleMutation
autoRoleRule: AutoRoleRuleMutation
level: LevelMutation
user: UserMutation
}

View File

@ -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]
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)
)

View File

@ -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)

View File

@ -16,7 +16,6 @@ class RemoveConfig:
build: BuildSettings,
post_build: PostBuildSettings,
):
self._env = env
self._workspace = ws
self._project = project