master #475
| @@ -81,7 +81,6 @@ jobs: | ||||
|         run: | | ||||
|           cd web | ||||
|           docker image prune -f | ||||
|           cp src/favicon.ico src/favicon.ico | ||||
|           npm run build | ||||
|           docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv) . | ||||
|  | ||||
|   | ||||
 Submodule bot/docker updated: 36ed43055d...fbcd9226c4
									
								
							| @@ -15,7 +15,7 @@ __title__ = "bot" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "3" | ||||
|       "Micro": "8" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
| @@ -16,7 +16,6 @@ | ||||
|     "LicenseName": "MIT", | ||||
|     "LicenseDescription": "MIT, see LICENSE for more details.", | ||||
|     "Dependencies": [ | ||||
|       "cpl-core==2023.10.1", | ||||
|       "cpl-translation==2023.4.0.post1", | ||||
|       "cpl-query==2023.10.0", | ||||
|       "cpl-discord==2023.10.0.post1", | ||||
| @@ -34,7 +33,8 @@ | ||||
|       "discord==2.3.2", | ||||
|       "bs4==0.0.1", | ||||
|       "lxml==4.9.3", | ||||
|       "python-valve==0.2.1" | ||||
|       "python-valve==0.2.1", | ||||
|       "cpl-core==2023.10.2" | ||||
|     ], | ||||
|     "DevDependencies": [ | ||||
|       "cpl-cli==2023.4.0.post3", | ||||
|   | ||||
 Submodule bot/src/bot/config updated: be5b15f227...eeebd13f80
									
								
							| @@ -15,7 +15,7 @@ __title__ = "bot.extension" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -2,22 +2,22 @@ | ||||
|   "api": { | ||||
|     "api": { | ||||
|       "test_mail": { | ||||
|         "message": "Dies ist eine Test-Mail vom Krümelmonster Web Interface\nGesendet von {}-{}", | ||||
|         "message": "Dies ist eine Test-Mail vom Krümelmonster Web Interface\r\nGesendet von {}-{}", | ||||
|         "subject": "Krümelmonster Web Interface Test-Mail" | ||||
|       } | ||||
|     }, | ||||
|     "auth": { | ||||
|       "confirmation": { | ||||
|         "message": "Öffne den Link, um die E-Mail zu bestätigen:\n{}auth/register/{}", | ||||
|         "message": "Öffne den Link, um die E-Mail zu bestätigen:\r\n{}auth/register/{}", | ||||
|         "subject": "E-Mail für {} {} bestätigen" | ||||
|       }, | ||||
|       "forgot_password": { | ||||
|         "message": "Öffne den Link, um das Passwort zu ändern:\n{}auth/forgot-password/{}", | ||||
|         "message": "Öffne den Link, um das Passwort zu ändern:\r\n{}auth/forgot-password/{}", | ||||
|         "subject": "Passwort für {} {} zurücksetzen" | ||||
|       } | ||||
|     }, | ||||
|     "mail": { | ||||
|       "automatic_mail": "\n\nDies ist eine automatische E-Mail.\nGesendet von {}-{}@{}" | ||||
|       "automatic_mail": "\r\n\r\nDies ist eine automatische E-Mail.\r\nGesendet von {}-{}@{}" | ||||
|     } | ||||
|   }, | ||||
|   "common": { | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.abc" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -114,3 +114,7 @@ class AuthServiceABC(ABC): | ||||
|     @abstractmethod | ||||
|     async def reset_password_async(self, rp_dto: ResetPasswordDTO): | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     async def resend_confirmation_email_by_mail(self, mail: str): | ||||
|         pass | ||||
|   | ||||
| @@ -16,8 +16,8 @@ from werkzeug.exceptions import NotFound | ||||
|  | ||||
| from bot_api.configuration.api_settings import ApiSettings | ||||
| from bot_api.configuration.authentication_settings import AuthenticationSettings | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_api.exception.service_exception import ServiceException | ||||
| from bot_core.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_exception import ServiceException | ||||
| from bot_api.logging.api_logger import ApiLogger | ||||
| from bot_api.model.error_dto import ErrorDTO | ||||
| from bot_api.route.route import Route | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "3" | ||||
|       "Micro": "8" | ||||
|     }, | ||||
|     "Author": "", | ||||
|     "AuthorEmail": "", | ||||
|   | ||||
 Submodule bot/src/bot_api/config updated: 521951b8ab...12ffcbcd9b
									
								
							| @@ -15,7 +15,7 @@ __title__ = "bot_api.configuration" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.controller" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -84,13 +84,13 @@ class AuthController: | ||||
|         self._auth_service.add_auth_user(dto) | ||||
|         return "", 200 | ||||
|  | ||||
|     @Route.post(f"{BasePath}/resend-confirmation-email-by-mail/<mail>") | ||||
|     async def resend_confirmation_email_by_user_id(self, mail: str): | ||||
|         await self._auth_service.resend_confirmation_email_by_mail(mail) | ||||
|         return "", 200 | ||||
|  | ||||
|     @Route.post(f"{BasePath}/register-by-id/<id>") | ||||
|     async def register_id(self, id: str): | ||||
|         if not FeatureFlagsSettings.get_flag_from_dict( | ||||
|             self._technician_config.feature_flags, FeatureFlagsEnum.basic_registration | ||||
|         ): | ||||
|             return | ||||
|  | ||||
|         result = await self._auth_service.confirm_email_async(id) | ||||
|         return jsonify(result) | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,7 @@ from bot_api.api import Api | ||||
| from bot_api.configuration.discord_authentication_settings import ( | ||||
|     DiscordAuthenticationSettings, | ||||
| ) | ||||
| from bot_core.exception.service_exception import ServiceException | ||||
| from bot_api.logging.api_logger import ApiLogger | ||||
| from bot_api.model.auth_user_dto import AuthUserDTO | ||||
| from bot_api.route.route import Route | ||||
| @@ -90,5 +91,10 @@ class AuthDiscordController: | ||||
|             AuthRoleEnum.normal, | ||||
|         ) | ||||
|  | ||||
|         result = await self._auth_service.login_discord_async(dto, response["id"]) | ||||
|         return jsonify(result.to_dict()) | ||||
|         try: | ||||
|             result = await self._auth_service.login_discord_async(dto, response["id"]) | ||||
|             return jsonify(result.to_dict()) | ||||
|         except ServiceException as e: | ||||
|             r = jsonify({"email": dto.email}) | ||||
|             r.status_code = 403 | ||||
|             return r | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.event" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -1,26 +0,0 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
|  | ||||
| """ | ||||
| bot sh-edraft.de Discord bot | ||||
| ~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Discord bot for customers of sh-edraft.de | ||||
|  | ||||
| :copyright: (c) 2022 - 2023 sh-edraft.de | ||||
| :license: MIT, see LICENSE for more details. | ||||
|  | ||||
| """ | ||||
|  | ||||
| __title__ = "bot_api.exception" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
|  | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.filter" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.filter.discord" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.logging" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.model" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.model.discord" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -1,10 +1,7 @@ | ||||
| import traceback | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.console import Console | ||||
|  | ||||
| from bot_api.abc.dto_abc import DtoABC | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_error_code_enum import ServiceErrorCode | ||||
|  | ||||
|  | ||||
| class ErrorDTO(DtoABC): | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.route" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -8,8 +8,8 @@ from flask import request, jsonify | ||||
| from flask_cors import cross_origin | ||||
|  | ||||
| from bot_api.abc.auth_service_abc import AuthServiceABC | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_api.exception.service_exception import ServiceException | ||||
| from bot_core.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_exception import ServiceException | ||||
| from bot_api.model.error_dto import ErrorDTO | ||||
| from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC | ||||
| from bot_data.model.auth_role_enum import AuthRoleEnum | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.service" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| import hashlib | ||||
| import re | ||||
| import textwrap | ||||
| import uuid | ||||
| from datetime import datetime, timedelta, timezone | ||||
| from threading import Thread | ||||
| @@ -19,8 +18,8 @@ from flask import request | ||||
| from bot_api.abc.auth_service_abc import AuthServiceABC | ||||
| 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_core.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_exception import ServiceException | ||||
| from bot_api.filter.auth_user_select_criteria import AuthUserSelectCriteria | ||||
| from bot_api.logging.api_logger import ApiLogger | ||||
| from bot_api.model.auth_user_dto import AuthUserDTO | ||||
| @@ -172,11 +171,7 @@ class AuthService(AuthServiceABC): | ||||
|         mail.add_header("Content-Transfer-Encoding: quoted-printable") | ||||
|         mail.add_receiver(str(email)) | ||||
|         mail.subject = subject | ||||
|         mail.body = textwrap.dedent( | ||||
|             f"""{message} | ||||
|         {self._t.transform('api.mail.automatic_mail').format(self._environment.application_name, self._environment.environment_name, self._environment.host_name)} | ||||
|         """ | ||||
|         ) | ||||
|         mail.body = f"{message}\r\n{self._t.transform('api.mail.automatic_mail').format(self._environment.application_name, self._environment.environment_name, self._environment.host_name)}" | ||||
|  | ||||
|         thr = Thread(target=self._mailer.send_mail, args=[mail]) | ||||
|         thr.start() | ||||
| @@ -599,3 +594,12 @@ class AuthService(AuthServiceABC): | ||||
|         user.forgot_password_id = None | ||||
|         self._auth_users.update_auth_user(user) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|     async def resend_confirmation_email_by_mail(self, mail: str): | ||||
|         user = self._auth_users.find_auth_user_by_email(mail) | ||||
|         if user is None: | ||||
|             raise ServiceException(ServiceErrorCode.InvalidUser, f"User not found") | ||||
|         if user.confirmation_id is None: | ||||
|             raise ServiceException(ServiceErrorCode.DataAlreadyExists, f"User already confirmed") | ||||
|  | ||||
|         self._send_confirmation_id_to_user(user) | ||||
|   | ||||
| @@ -4,8 +4,8 @@ from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_api.abc.auth_service_abc import AuthServiceABC | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_api.exception.service_exception import ServiceException | ||||
| from bot_core.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_exception import ServiceException | ||||
| from bot_api.filter.discord.server_select_criteria import ServerSelectCriteria | ||||
| from bot_api.model.discord.server_dto import ServerDTO | ||||
| from bot_api.model.discord.server_filtered_result_dto import ServerFilteredResultDTO | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_api.transformer" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -35,21 +35,37 @@ class AuthUserTransformer(TransformerABC): | ||||
|     @ServiceProviderABC.inject | ||||
|     def _is_technician(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): | ||||
|         guild = bot.get_guild(user.server.discord_id) | ||||
|         if guild is None: | ||||
|             return permissions.is_member_technician_by_id(user.discord_id) | ||||
|  | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         if member is None: | ||||
|             return permissions.is_member_technician_by_id(user.discord_id) | ||||
|  | ||||
|         return permissions.is_member_technician(member) | ||||
|  | ||||
|     @staticmethod | ||||
|     @ServiceProviderABC.inject | ||||
|     def _is_admin(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): | ||||
|         guild = bot.get_guild(user.server.discord_id) | ||||
|         if guild is None: | ||||
|             return False | ||||
|  | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         if member is None: | ||||
|             return False | ||||
|         return permissions.is_member_admin(member) | ||||
|  | ||||
|     @staticmethod | ||||
|     @ServiceProviderABC.inject | ||||
|     def _is_moderator(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC): | ||||
|         guild = bot.get_guild(user.server.discord_id) | ||||
|         if guild is None: | ||||
|             return False | ||||
|  | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         if member is None: | ||||
|             return False | ||||
|         return permissions.is_member_moderator(member) | ||||
|  | ||||
|     @classmethod | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.abc" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -19,3 +19,7 @@ class PermissionServiceABC(ABC): | ||||
|     @abstractmethod | ||||
|     def is_member_technician(self, member: discord.Member) -> bool: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def is_member_technician_by_id(self, member_id: int) -> bool: | ||||
|         pass | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "3" | ||||
|       "Micro": "8" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.configuration" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.core_extension" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.events" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.exception" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_error_code_enum import ServiceErrorCode | ||||
| 
 | ||||
| 
 | ||||
| class ServiceException(Exception): | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.helper" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.logging" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.pipes" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_core.service" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -5,11 +5,11 @@ from cpl_core.configuration import ConfigurationABC | ||||
| from cpl_core.logging import LoggerABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_core.abc.permission_service_abc import PermissionServiceABC | ||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC | ||||
| from bot_data.model.team_member_type_enum import TeamMemberTypeEnum | ||||
| from bot_core.abc.permission_service_abc import PermissionServiceABC | ||||
|  | ||||
|  | ||||
| class PermissionService(PermissionServiceABC): | ||||
| @@ -112,3 +112,18 @@ class PermissionService(PermissionServiceABC): | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, "Permission check failed", e) | ||||
|             return False | ||||
|  | ||||
|     def is_member_technician_by_id(self, member_id: int): | ||||
|         has_permission_cached = self.get_cached_permission(member_id, TeamMemberTypeEnum.technician) | ||||
|         if has_permission_cached is not None: | ||||
|             return has_permission_cached | ||||
|  | ||||
|         self._logger.debug(__name__, f"Checking is member {member_id} technician") | ||||
|  | ||||
|         try: | ||||
|             has_permission = member_id in self._technician_configs.get_technician_config().technician_ids | ||||
|             self.set_cached_permission(has_permission, member_id, TeamMemberTypeEnum.technician) | ||||
|             return has_permission | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, "Permission check failed", e) | ||||
|             return False | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data.abc" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -18,6 +18,10 @@ class UserWarningsRepositoryABC(ABC): | ||||
|     def get_user_warnings_by_id(self, id: int) -> UserWarnings: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_user_warnings_by_server_id(self, server_id: int) -> List[UserWarnings]: | ||||
|         pass | ||||
|  | ||||
|     @abstractmethod | ||||
|     def get_user_warnings_by_user_id(self, user_id: int) -> List[UserWarnings]: | ||||
|         pass | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "3" | ||||
|       "Micro": "8" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
|   | ||||
							
								
								
									
										50
									
								
								bot/src/bot_data/db_connection.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								bot/src/bot_data/db_connection.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import DatabaseSettings | ||||
| from cpl_core.database.connection import DatabaseConnectionABC | ||||
| from mysql.connector.abstracts import MySQLConnectionAbstract | ||||
| from mysql.connector.cursor import MySQLCursorBuffered | ||||
|  | ||||
|  | ||||
| class DBConnection(DatabaseConnectionABC): | ||||
|     def __init__(self): | ||||
|         DatabaseConnectionABC.__init__(self) | ||||
|  | ||||
|         self._database: Optional[MySQLConnectionAbstract] = None | ||||
|         self._cursor: Optional[MySQLCursorBuffered] = None | ||||
|  | ||||
|     @property | ||||
|     def server(self) -> MySQLConnectionAbstract: | ||||
|         return self._database | ||||
|  | ||||
|     @property | ||||
|     def cursor(self) -> MySQLCursorBuffered: | ||||
|         return self._cursor | ||||
|  | ||||
|     def connect(self, settings: DatabaseSettings): | ||||
|         # connection = sql.connect( | ||||
|         #     host=settings.host, | ||||
|         #     port=settings.port, | ||||
|         #     user=settings.user, | ||||
|         #     passwd=CredentialManager.decrypt(settings.password), | ||||
|         #     charset=settings.charset, | ||||
|         #     use_unicode=settings.use_unicode, | ||||
|         #     buffered=settings.buffered, | ||||
|         #     auth_plugin=settings.auth_plugin, | ||||
|         #     ssl_disabled=settings.ssl_disabled, | ||||
|         # ) | ||||
|         # connection.cursor().execute(f"CREATE DATABASE IF NOT EXISTS `{settings.database}`;") | ||||
|         # self._database = sql.connect( | ||||
|         #     host=settings.host, | ||||
|         #     port=settings.port, | ||||
|         #     user=settings.user, | ||||
|         #     passwd=CredentialManager.decrypt(settings.password), | ||||
|         #     db=settings.database, | ||||
|         #     charset=settings.charset, | ||||
|         #     use_unicode=settings.use_unicode, | ||||
|         #     buffered=settings.buffered, | ||||
|         #     auth_plugin=settings.auth_plugin, | ||||
|         #     ssl_disabled=settings.ssl_disabled, | ||||
|         # ) | ||||
|         self._ | ||||
|         self._cursor = self._database.cursor() | ||||
| @@ -1,9 +1,12 @@ | ||||
| import time | ||||
| import uuid | ||||
|  | ||||
| from cpl_core.database import DatabaseSettings | ||||
| from cpl_core.database.context import DatabaseContext | ||||
|  | ||||
| from bot_core.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_exception import ServiceException | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| from bot_data.mysql_pool import MySQLPool | ||||
|  | ||||
|  | ||||
| class DBContext(DatabaseContext): | ||||
| @@ -11,36 +14,45 @@ class DBContext(DatabaseContext): | ||||
|         self._logger = logger | ||||
|  | ||||
|         DatabaseContext.__init__(self) | ||||
|         self._pool: MySQLPool = None | ||||
|         self._fails = 0 | ||||
|  | ||||
|     def connect(self, database_settings: DatabaseSettings): | ||||
|         try: | ||||
|             self._logger.debug(__name__, "Connecting to database") | ||||
|             self._db.connect(database_settings) | ||||
|             self._pool = MySQLPool(database_settings) | ||||
|             self._pool.execute(f"CREATE DATABASE IF NOT EXISTS `{database_settings.database}`;", commit=True) | ||||
|             self._logger.info(__name__, "Connected to database") | ||||
|         except Exception as e: | ||||
|             self._logger.fatal(__name__, "Connecting to database failed", e) | ||||
|  | ||||
|     @property | ||||
|     def cursor(self): | ||||
|         return self | ||||
|  | ||||
|     def save_changes(self): | ||||
|         try: | ||||
|             self._logger.trace(__name__, "Save changes") | ||||
|             super(DBContext, self).save_changes() | ||||
|             self._logger.debug(__name__, "Saved changes") | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, "Saving changes failed", e) | ||||
|         pass | ||||
|  | ||||
|     def select(self, statement: str) -> list[tuple]: | ||||
|         try: | ||||
|             return super(DBContext, self).select(statement) | ||||
|             return self._pool.execute(statement) | ||||
|         except Exception as e: | ||||
|             if self._fails >= 3: | ||||
|                 self._logger.fatal(__name__, f"Database error caused by {statement}", e) | ||||
|                 self._logger.error(__name__, f"Database error caused by {statement}", e) | ||||
|                 uid = uuid.uuid4() | ||||
|                 raise ServiceException( | ||||
|                     ServiceErrorCode.Unknown, | ||||
|                     f"Query failed three times with {type(e).__name__}. Contact an admin and give them the UID: {uid}", | ||||
|                 ) | ||||
|  | ||||
|             self._logger.error(__name__, f"Database error caused by {statement}", e) | ||||
|             self._fails += 1 | ||||
|             try: | ||||
|                 time.sleep(0.5) | ||||
|                 self._logger.debug(__name__, "Retry select") | ||||
|                 return self.select(statement) | ||||
|             except Exception as e: | ||||
|                 pass | ||||
|             return [] | ||||
|  | ||||
|     def execute(self, statement: str): | ||||
|         return self._pool.execute(statement, commit=True) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data.model" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -258,6 +258,15 @@ class AuthUser(TableABC): | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_relations_string(self) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|             DELETE FROM `AuthUserUsersRelations` | ||||
|             WHERE `AuthUserId` = {self._auth_user_id}; | ||||
|         """ | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def delete_string(self) -> str: | ||||
|         return str( | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| @@ -48,8 +49,10 @@ class AutoRoleRule(TableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.auto_role.server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return guild.get_role(self.role_id).name | ||||
|  | ||||
|     @role_id.setter | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| @@ -43,6 +45,8 @@ class AutoRoleRuleHistory(HistoryTableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.auto_role.server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return guild.get_role(self.role_id).name | ||||
|   | ||||
| @@ -2,6 +2,10 @@ from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
| from discord import Role | ||||
|  | ||||
| from bot_data.model.server import Server | ||||
|  | ||||
| @@ -33,6 +37,15 @@ class Level(TableABC): | ||||
|     def id(self) -> int: | ||||
|         return self._id | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         role = List(Role, guild.roles).where(lambda x: x.name == self._name).first_or_default() | ||||
|         return None if role is None else role.icon | ||||
|  | ||||
|     @property | ||||
|     def name(self) -> str: | ||||
|         return self._name | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| @@ -30,14 +31,18 @@ class Server(TableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def name(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def name(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return None if guild is None else guild.name | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return None if guild is None else guild.icon.url | ||||
|  | ||||
|     @staticmethod | ||||
|   | ||||
| @@ -32,6 +32,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|         default_role_id: Optional[int], | ||||
|         short_role_name_only_set_highest_role: bool, | ||||
|         game_offer_notification_chat_id: int, | ||||
|         reset_member_after_rejoin: bool, | ||||
|         feature_flags: dict[FeatureFlagsEnum], | ||||
|         server: Server, | ||||
|         afk_channel_ids: List[int], | ||||
| @@ -58,6 +59,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|         self._default_role_id = default_role_id | ||||
|         self._short_role_name_only_set_highest_role = short_role_name_only_set_highest_role | ||||
|         self._game_offer_notification_chat_id = game_offer_notification_chat_id | ||||
|         self._reset_member_after_rejoin = reset_member_after_rejoin | ||||
|  | ||||
|         self._feature_flags = feature_flags | ||||
|         self._server = server | ||||
| @@ -88,6 +90,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|             None, | ||||
|             False, | ||||
|             guild.system_channel.id, | ||||
|             False, | ||||
|             {}, | ||||
|             server, | ||||
|             List(int), | ||||
| @@ -234,6 +237,14 @@ class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|     def game_offer_notification_chat_id(self, value: int): | ||||
|         self._game_offer_notification_chat_id = value | ||||
|  | ||||
|     @property | ||||
|     def reset_member_after_rejoin(self) -> bool: | ||||
|         return self._reset_member_after_rejoin | ||||
|  | ||||
|     @reset_member_after_rejoin.setter | ||||
|     def reset_member_after_rejoin(self, value: bool): | ||||
|         self._reset_member_after_rejoin = value | ||||
|  | ||||
|     @property | ||||
|     def feature_flags(self) -> dict[FeatureFlagsEnum]: | ||||
|         return self._feature_flags | ||||
| @@ -310,6 +321,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|                     `DefaultRoleId`, | ||||
|                     `ShortRoleNameSetOnlyHighest`, | ||||
|                     `GameOfferNotificationChatId`, | ||||
|                     `ResetMemberAfterRejoin`, | ||||
|                     `FeatureFlags`, | ||||
|                     `ServerId` | ||||
|                 ) VALUES ( | ||||
| @@ -330,6 +342,7 @@ class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|                     {"NULL" if self._default_role_id is None else self._default_role_id}, | ||||
|                     {self._short_role_name_only_set_highest_role}, | ||||
|                     {self._game_offer_notification_chat_id}, | ||||
|                     {self._reset_member_after_rejoin}, | ||||
|                     '{json.dumps(self._feature_flags)}', | ||||
|                     {self._server.id} | ||||
|                 ); | ||||
| @@ -357,7 +370,8 @@ class ServerConfig(TableABC, ConfigurationModelABC): | ||||
|                 `LoginMessageChannelId` = {self._login_message_channel_id}, | ||||
|                 `DefaultRoleId` = {"NULL" if self._default_role_id is None else self._default_role_id}, | ||||
|                 `ShortRoleNameSetOnlyHighest` = {self._short_role_name_only_set_highest_role}, | ||||
|                 `GameOfferNotificationChatId` = {self._game_offer_notification_chat_id}, | ||||
|                 `GameOfferNotificationChatId` = {"NULL" if self._game_offer_notification_chat_id is None else self._game_offer_notification_chat_id}, | ||||
|                 `ResetMemberAfterRejoin` = {self._reset_member_after_rejoin}, | ||||
|                 `FeatureFlags` = '{json.dumps(self._feature_flags)}', | ||||
|                 `ServerId` = {self._server.id} | ||||
|                 WHERE `Id` = {self._id}; | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| @@ -32,12 +34,16 @@ class ServerHistory(HistoryTableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def name(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def name(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return None if guild is None else guild.name | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return None if guild is None else guild.icon.url | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database import TableABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| @@ -51,8 +52,10 @@ class ShortRoleName(TableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self._server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return guild.get_role(self.role_id).name | ||||
|  | ||||
|     @property | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| @@ -47,8 +49,10 @@ class ShortRoleNameHistory(HistoryTableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self._server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         return guild.get_role(self.role_id).name | ||||
|  | ||||
|     @property | ||||
|   | ||||
| @@ -38,6 +38,11 @@ class User(TableABC): | ||||
|         self._created_at = created_at if created_at is not None else self._created_at | ||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at | ||||
|  | ||||
|     def reset(self): | ||||
|         self._xp = 0 | ||||
|         self._message_count = 0 | ||||
|         self._reaction_count = 0 | ||||
|  | ||||
|     @property | ||||
|     def id(self) -> int: | ||||
|         return self._user_id | ||||
| @@ -48,15 +53,19 @@ class User(TableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def name(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def name(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         user = guild.get_member(self.discord_id) | ||||
|         return None if user is None else user.name | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         user = guild.get_member(self.discord_id) | ||||
|         return None if user is None else user.display_icon | ||||
|  | ||||
| @@ -132,7 +141,7 @@ class User(TableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def level(self, services: ServiceProviderABC) -> Level: | ||||
|     def level(self, services: ServiceProviderABC) -> Optional[Level]: | ||||
|         from modules.level.service.level_service import LevelService | ||||
|  | ||||
|         levels: LevelService = services.get_service(LevelService) | ||||
| @@ -170,10 +179,12 @@ class User(TableABC): | ||||
|  | ||||
|     @property | ||||
|     @ServiceProviderABC.inject | ||||
|     def profile_picture_url(self, bot: DiscordBotServiceABC) -> str: | ||||
|     def profile_picture_url(self, bot: DiscordBotServiceABC) -> Optional[str]: | ||||
|         guild = bot.get_guild(self.server.discord_id) | ||||
|         if guild is None: | ||||
|             return None | ||||
|         user = guild.get_member(self._discord_id) | ||||
|         return None if user is None else user.avatar.url | ||||
|         return None if user is None or user.avatar is None else user.avatar.url | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_all_string() -> str: | ||||
|   | ||||
| @@ -59,6 +59,17 @@ class UserWarnings(TableABC): | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_server_id_string(id: int) -> str: | ||||
|         return str( | ||||
|             f""" | ||||
|                 SELECT `UserWarnings`.* FROM `UserWarnings` | ||||
|                 INNER JOIN `Users` | ||||
|                 ON `Users`.`UserId` = `UserWarnings`.`UserId` | ||||
|                 WHERE `Users`.`ServerId` = {id}; | ||||
|             """ | ||||
|         ) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_select_by_user_id_string(id: int) -> str: | ||||
|         return str( | ||||
|   | ||||
							
								
								
									
										104
									
								
								bot/src/bot_data/mysql_pool.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								bot/src/bot_data/mysql_pool.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| # https://stackoverflow.com/questions/32658679/how-to-create-a-mysql-connection-pool-or-any-better-way-to-initialize-the-multip | ||||
| import mysql.connector as sql | ||||
| from cpl_core.database import DatabaseSettings | ||||
| from cpl_core.utils import CredentialManager | ||||
|  | ||||
|  | ||||
| class MySQLPool(object): | ||||
|     """ | ||||
|     create a pool when connect mysql, which will decrease the time spent in | ||||
|     request connection, create connection and close connection. | ||||
|     """ | ||||
|  | ||||
|     def __init__( | ||||
|         self, | ||||
|         database_settings: DatabaseSettings, | ||||
|         pool_size=5, | ||||
|     ): | ||||
|         res = { | ||||
|             "host": database_settings.host, | ||||
|             "port": database_settings.port, | ||||
|             "user": database_settings.user, | ||||
|             "password": CredentialManager.decrypt(database_settings.password), | ||||
|             "database": database_settings.database, | ||||
|         } | ||||
|  | ||||
|         self.dbconfig = res | ||||
|         self.pool = self.create_pool(pool_name="MySqlPool", pool_size=pool_size) | ||||
|  | ||||
|     def create_pool(self, pool_name="MySqlPool", pool_size=3): | ||||
|         """ | ||||
|         Create a connection pool, after created, the request of connecting | ||||
|         MySQL could get a connection from this pool instead of request to | ||||
|         create a connection. | ||||
|         :param pool_name: the name of pool, default is "mypool" | ||||
|         :param pool_size: the size of pool, default is 3 | ||||
|         :return: connection pool | ||||
|         """ | ||||
|         pool = sql.pooling.MySQLConnectionPool( | ||||
|             pool_name=pool_name, pool_size=pool_size, pool_reset_session=True, **self.dbconfig | ||||
|         ) | ||||
|         return pool | ||||
|  | ||||
|     def close(self, conn, cursor): | ||||
|         """ | ||||
|         A method used to close connection of mysql. | ||||
|         :param conn: | ||||
|         :param cursor: | ||||
|         :return: | ||||
|         """ | ||||
|         cursor.close() | ||||
|         conn.close() | ||||
|  | ||||
|     def execute(self, sql, args=None, commit=False): | ||||
|         """ | ||||
|         Execute a sql, it could be with args and with out args. The usage is | ||||
|         similar with execute() function in module pymysql. | ||||
|         :param sql: sql clause | ||||
|         :param args: args need by sql clause | ||||
|         :param commit: whether to commit | ||||
|         :return: if commit, return None, else, return result | ||||
|         """ | ||||
|         # get connection form connection pool instead of create one. | ||||
|         conn = self.pool.get_connection() | ||||
|         cursor = conn.cursor() | ||||
|         if args: | ||||
|             cursor.execute(sql, args) | ||||
|         else: | ||||
|             cursor.execute(sql) | ||||
|         if commit is True: | ||||
|             conn.commit() | ||||
|             self.close(conn, cursor) | ||||
|             return None | ||||
|         else: | ||||
|             res = cursor.fetchall() | ||||
|             self.close(conn, cursor) | ||||
|             return res | ||||
|  | ||||
|     def executemany(self, sql, args, commit=False): | ||||
|         """ | ||||
|         Execute with many args. Similar with executemany() function in pymysql. | ||||
|         args should be a sequence. | ||||
|         :param sql: sql clause | ||||
|         :param args: args | ||||
|         :param commit: commit or not. | ||||
|         :return: if commit, return None, else, return result | ||||
|         """ | ||||
|         # get connection form connection pool instead of create one. | ||||
|         conn = self.pool.get_connection() | ||||
|         cursor = conn.cursor() | ||||
|         cursor.executemany(sql, args) | ||||
|         if commit is True: | ||||
|             conn.commit() | ||||
|             self.close(conn, cursor) | ||||
|             return None | ||||
|         else: | ||||
|             res = cursor.fetchall() | ||||
|             self.close(conn, cursor) | ||||
|             return res | ||||
|  | ||||
|     def commit(self): | ||||
|         conn = self.pool.get_connection() | ||||
|         conn.commit() | ||||
|         cursor = conn.cursor() | ||||
|         self.close(conn, cursor) | ||||
| @@ -0,0 +1,7 @@ | ||||
| ALTER TABLE CFG_Server | ||||
|     DROP COLUMN ResetMemberAfterRejoin; | ||||
|  | ||||
| ALTER TABLE CFG_ServerHistory | ||||
|     DROP COLUMN ResetMemberAfterRejoin; | ||||
|  | ||||
|  | ||||
							
								
								
									
										116
									
								
								bot/src/bot_data/scripts/1.2.4/1_ResetMemberAfterRejoin_up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								bot/src/bot_data/scripts/1.2.4/1_ResetMemberAfterRejoin_up.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| ALTER TABLE CFG_Server | ||||
|     ADD ResetMemberAfterRejoin BOOLEAN NOT NULL DEFAULT FALSE AFTER GameOfferNotificationChatId; | ||||
|  | ||||
|  | ||||
|  | ||||
| ALTER TABLE CFG_ServerHistory | ||||
|     ADD ResetMemberAfterRejoin BOOLEAN NOT NULL DEFAULT FALSE AFTER GameOfferNotificationChatId; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerUpdate`;; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerUpdate` | ||||
|     AFTER UPDATE | ||||
|     ON `CFG_Server` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerHistory` (`Id`, | ||||
|                                      `MessageDeleteTimer`, | ||||
|                                      `NotificationChatId`, | ||||
|                                      `MaxVoiceStateHours`, | ||||
|                                      `XpPerMessage`, | ||||
|                                      `XpPerReaction`, | ||||
|                                      `MaxMessageXpPerHour`, | ||||
|                                      `XpPerOntimeHour`, | ||||
|                                      `XpPerEventParticipation`, | ||||
|                                      `XpPerAchievement`, | ||||
|                                      `AFKCommandChannelId`, | ||||
|                                      `HelpVoiceChannelId`, | ||||
|                                      `TeamChannelId`, | ||||
|                                      `LoginMessageChannelId`, | ||||
|                                      `DefaultRoleId`, | ||||
|                                      `ShortRoleNameSetOnlyHighest`, | ||||
|                                      `GameOfferNotificationChatId`, | ||||
|                                      `ResetMemberAfterRejoin`, | ||||
|                                      `FeatureFlags`, | ||||
|                                      `ServerId`, | ||||
|                                      `DateFrom`, | ||||
|                                      `DateTo`) | ||||
|     VALUES (OLD.Id, | ||||
|             OLD.MessageDeleteTimer, | ||||
|             OLD.NotificationChatId, | ||||
|             OLD.MaxVoiceStateHours, | ||||
|             OLD.XpPerMessage, | ||||
|             OLD.XpPerReaction, | ||||
|             OLD.MaxMessageXpPerHour, | ||||
|             OLD.XpPerOntimeHour, | ||||
|             OLD.XpPerEventParticipation, | ||||
|             OLD.XpPerAchievement, | ||||
|             OLD.AFKCommandChannelId, | ||||
|             OLD.HelpVoiceChannelId, | ||||
|             OLD.TeamChannelId, | ||||
|             OLD.LoginMessageChannelId, | ||||
|             OLD.DefaultRoleId, | ||||
|             OLD.ShortRoleNameSetOnlyHighest, | ||||
|             OLD.GameOfferNotificationChatId, | ||||
|             OLD.ResetMemberAfterRejoin, | ||||
|             OLD.FeatureFlags, | ||||
|             OLD.ServerId, | ||||
|             OLD.LastModifiedAt, | ||||
|             CURRENT_TIMESTAMP(6)); | ||||
| END;; | ||||
|  | ||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerDelete`;; | ||||
|  | ||||
| CREATE TRIGGER `TR_CFG_ServerDelete` | ||||
|     AFTER DELETE | ||||
|     ON `CFG_Server` | ||||
|     FOR EACH ROW | ||||
| BEGIN | ||||
|     INSERT INTO `CFG_ServerHistory` (`Id`, | ||||
|                                      `MessageDeleteTimer`, | ||||
|                                      `NotificationChatId`, | ||||
|                                      `MaxVoiceStateHours`, | ||||
|                                      `XpPerMessage`, | ||||
|                                      `XpPerReaction`, | ||||
|                                      `MaxMessageXpPerHour`, | ||||
|                                      `XpPerOntimeHour`, | ||||
|                                      `XpPerEventParticipation`, | ||||
|                                      `XpPerAchievement`, | ||||
|                                      `AFKCommandChannelId`, | ||||
|                                      `HelpVoiceChannelId`, | ||||
|                                      `TeamChannelId`, | ||||
|                                      `LoginMessageChannelId`, | ||||
|                                      `DefaultRoleId`, | ||||
|                                      `ShortRoleNameSetOnlyHighest`, | ||||
|                                      `GameOfferNotificationChatId`, | ||||
|                                      `ResetMemberAfterRejoin`, | ||||
|                                      `ServerId`, | ||||
|                                      `FeatureFlags`, | ||||
|                                      `Deleted`, | ||||
|                                      `DateFrom`, | ||||
|                                      `DateTo`) | ||||
|     VALUES (OLD.Id, | ||||
|             OLD.MessageDeleteTimer, | ||||
|             OLD.NotificationChatId, | ||||
|             OLD.MaxVoiceStateHours, | ||||
|             OLD.XpPerMessage, | ||||
|             OLD.XpPerReaction, | ||||
|             OLD.MaxMessageXpPerHour, | ||||
|             OLD.XpPerOntimeHour, | ||||
|             OLD.XpPerEventParticipation, | ||||
|             OLD.XpPerAchievement, | ||||
|             OLD.AFKCommandChannelId, | ||||
|             OLD.HelpVoiceChannelId, | ||||
|             OLD.TeamChannelId, | ||||
|             OLD.LoginMessageChannelId, | ||||
|             OLD.DefaultRoleId, | ||||
|             OLD.ShortRoleNameSetOnlyHighest, | ||||
|             OLD.GameOfferNotificationChatId, | ||||
|             OLD.ResetMemberAfterRejoin, | ||||
|             OLD.FeatureFlags, | ||||
|             OLD.ServerId, | ||||
|             TRUE, | ||||
|             OLD.LastModifiedAt, | ||||
|             CURRENT_TIMESTAMP(6)); | ||||
| END;; | ||||
|  | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_data.service" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -164,6 +164,7 @@ class AuthUserRepositoryService(AuthUserRepositoryABC): | ||||
|  | ||||
|     def delete_auth_user(self, user: AuthUser): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {user.delete_string}") | ||||
|         self._context.cursor.execute(user.delete_relations_string) | ||||
|         self._context.cursor.execute(user.delete_string) | ||||
|  | ||||
|     def add_auth_user_user_rel(self, rel: AuthUserUsersRelation): | ||||
|   | ||||
| @@ -37,6 +37,8 @@ class LevelRepositoryService(LevelRepositoryABC): | ||||
|             int(self._get_value_from_result(sql_result[3])),  # min xp | ||||
|             int(self._get_value_from_result(sql_result[4])),  # permissions | ||||
|             self._servers.get_server_by_id(sql_result[5]),  # server | ||||
|             sql_result[6],  # created_at | ||||
|             sql_result[7],  # modified_at | ||||
|             id=self._get_value_from_result(sql_result[0]),  # id | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| import glob | ||||
| import os | ||||
|  | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_core.dependency_injection import ServiceProviderABC | ||||
| from cpl_query.extension import List | ||||
| from packaging import version | ||||
|  | ||||
| import bot | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| from bot_data.db_context import DBContext | ||||
| from bot_data.model.migration import Migration | ||||
| from bot_data.model.migration_history import MigrationHistory | ||||
|  | ||||
| @@ -17,13 +17,12 @@ class MigrationService: | ||||
|         self, | ||||
|         logger: DatabaseLogger, | ||||
|         services: ServiceProviderABC, | ||||
|         db: DatabaseContextABC, | ||||
|         db: DBContext, | ||||
|     ): | ||||
|         self._logger = logger | ||||
|         self._services = services | ||||
|  | ||||
|         self._db = db | ||||
|         self._cursor = db.cursor | ||||
|  | ||||
|     def _get_migration_history(self) -> List[MigrationHistory]: | ||||
|         results = self._db.select( | ||||
| @@ -42,7 +41,7 @@ class MigrationService: | ||||
|             return | ||||
|  | ||||
|         self._logger.debug(__name__, f"Migrate new migration {migration.migration_id} to old method") | ||||
|         self._cursor.execute(migration.change_id_string(f"{migration.migration_id}Migration")) | ||||
|         self._db.execute(migration.change_id_string(f"{migration.migration_id}Migration")) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|     def _migration_migrations_to_new(self, migration: MigrationHistory): | ||||
| @@ -50,12 +49,11 @@ class MigrationService: | ||||
|             return | ||||
|  | ||||
|         self._logger.debug(__name__, f"Migrate old migration {migration.migration_id} to new method") | ||||
|         self._cursor.execute(migration.change_id_string(migration.migration_id.replace("Migration", ""))) | ||||
|         self._db.execute(migration.change_id_string(migration.migration_id.replace("Migration", ""))) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|     def _migrate_from_old_to_new(self): | ||||
|         self._cursor.execute("SHOW TABLES LIKE 'MigrationHistory'") | ||||
|         result = self._cursor.fetchone() | ||||
|         result = self._db.select("SHOW TABLES LIKE 'MigrationHistory'") | ||||
|         if not result: | ||||
|             return | ||||
|  | ||||
| @@ -120,8 +118,7 @@ class MigrationService: | ||||
|             active_statement = "" | ||||
|             try: | ||||
|                 # check if table exists | ||||
|                 self._cursor.execute("SHOW TABLES LIKE 'MigrationHistory'") | ||||
|                 result = self._cursor.fetchone() | ||||
|                 result = self._db.select("SHOW TABLES LIKE 'MigrationHistory'") | ||||
|                 if result: | ||||
|                     # there is a table named "tableName" | ||||
|                     self._logger.trace( | ||||
| @@ -142,9 +139,9 @@ class MigrationService: | ||||
|                     if statement in ["", "\n"]: | ||||
|                         continue | ||||
|                     active_statement = statement | ||||
|                     self._cursor.execute(statement + ";") | ||||
|                     self._db.execute(statement + ";") | ||||
|  | ||||
|                 self._cursor.execute( | ||||
|                 self._db.execute( | ||||
|                     MigrationHistory(migration.name).insert_string | ||||
|                     if upgrade | ||||
|                     else MigrationHistory(migration.name).delete_string | ||||
|   | ||||
| @@ -79,12 +79,13 @@ class ServerConfigRepositoryService(ServerConfigRepositoryABC): | ||||
|             result[15], | ||||
|             result[16], | ||||
|             result[17], | ||||
|             json.loads(result[18]), | ||||
|             self._servers.get_server_by_id(result[19]), | ||||
|             self._get_afk_channel_ids(result[19]), | ||||
|             self._get_team_role_ids(result[19]), | ||||
|             result[20], | ||||
|             result[18], | ||||
|             json.loads(result[19]), | ||||
|             self._servers.get_server_by_id(result[20]), | ||||
|             self._get_afk_channel_ids(result[20]), | ||||
|             self._get_team_role_ids(result[20]), | ||||
|             result[21], | ||||
|             result[22], | ||||
|             id=result[0], | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,7 @@ from datetime import datetime | ||||
| from typing import Optional | ||||
|  | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_core.time import TimeFormatSettings | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_core.logging.database_logger import DatabaseLogger | ||||
| @@ -15,12 +16,14 @@ from bot_data.model.user_message_count_per_hour import UserMessageCountPerHour | ||||
| class UserMessageCountPerHourRepositoryService(UserMessageCountPerHourRepositoryABC): | ||||
|     def __init__( | ||||
|         self, | ||||
|         time_format: TimeFormatSettings, | ||||
|         logger: DatabaseLogger, | ||||
|         db_context: DatabaseContextABC, | ||||
|         users: UserRepositoryABC, | ||||
|     ): | ||||
|         UserMessageCountPerHourRepositoryABC.__init__(self) | ||||
|  | ||||
|         self._time_format = time_format | ||||
|         self._logger = logger | ||||
|         self._context = db_context | ||||
|         self._users = users | ||||
| @@ -67,7 +70,12 @@ class UserMessageCountPerHourRepositoryService(UserMessageCountPerHourRepository | ||||
|     ) -> UserMessageCountPerHour: | ||||
|         sql = UserMessageCountPerHour.get_select_by_user_id_and_date_string(user_id, date) | ||||
|         self._logger.trace(__name__, f"Send SQL command: {sql}") | ||||
|         return self._from_result(self._context.select(sql)[0]) | ||||
|         res = self._context.select(sql) | ||||
|         if len(res) > 0: | ||||
|             return self._from_result(res[0]) | ||||
|  | ||||
|         user = self._users.get_user_by_id(user_id) | ||||
|         return UserMessageCountPerHour(date.strftime(self._time_format.date_time_format), date.hour, 0, user) | ||||
|  | ||||
|     def find_user_message_count_per_hour_by_user_id_and_date( | ||||
|         self, user_id: int, date: datetime | ||||
|   | ||||
| @@ -56,6 +56,20 @@ class UserWarningsRepositoryService(UserWarningsRepositoryABC): | ||||
|         self._logger.trace(__name__, f"Send SQL command: {UserWarnings.get_select_by_id_string(id)}") | ||||
|         return self._from_result(self._context.select(UserWarnings.get_select_by_id_string(id))[0]) | ||||
|  | ||||
|     def get_user_warnings_by_server_id(self, server_id: int) -> List[UserWarnings]: | ||||
|         self._logger.trace( | ||||
|             __name__, | ||||
|             f"Send SQL command: {UserWarnings.get_select_by_server_id_string(server_id)}", | ||||
|         ) | ||||
|  | ||||
|         return List( | ||||
|             UserWarnings, | ||||
|             [ | ||||
|                 self._from_result(warning) | ||||
|                 for warning in self._context.select(UserWarnings.get_select_by_server_id_string(server_id)) | ||||
|             ], | ||||
|         ) | ||||
|  | ||||
|     def get_user_warnings_by_user_id(self, user_id: int) -> List[UserWarnings]: | ||||
|         self._logger.trace( | ||||
|             __name__, | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_graphql" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_graphql.abc" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -7,8 +7,8 @@ from cpl_core.type import T | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_api.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_api.exception.service_exception import ServiceException | ||||
| from bot_core.exception.service_error_code_enum import ServiceErrorCode | ||||
| from bot_core.exception.service_exception import ServiceException | ||||
| from bot_api.route.route import Route | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
| from bot_core.environment_variables import MAINTENANCE | ||||
| @@ -30,6 +30,7 @@ from bot_data.model.user_joined_game_server import UserJoinedGameServer | ||||
| from bot_data.model.user_joined_server import UserJoinedServer | ||||
| from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel | ||||
| from bot_data.model.user_role_enum import UserRoleEnum | ||||
| from bot_data.model.user_warnings import UserWarnings | ||||
| from bot_graphql.abc.filter_abc import FilterABC | ||||
| from bot_graphql.filter.page import Page | ||||
| from bot_graphql.filter.sort import Sort | ||||
| @@ -90,7 +91,7 @@ class QueryABC(ObjectType): | ||||
|  | ||||
|         for u in user.users: | ||||
|             guild = bot.get_guild(u.server.discord_id) | ||||
|             if permissions.is_member_technician(guild.get_member(u.discord_id)): | ||||
|             if guild is not None and permissions.is_member_technician(guild.get_member(u.discord_id)): | ||||
|                 return True | ||||
|  | ||||
|         if config.get_configuration(MAINTENANCE): | ||||
| @@ -101,9 +102,7 @@ class QueryABC(ObjectType): | ||||
|             element: Achievement = element | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member) and u.server.id == element.server.id: | ||||
|                 if u.server.id == element.server.id: | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
| @@ -112,6 +111,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member) and u.server.id == element.server.id: | ||||
|                     access = True | ||||
| @@ -122,6 +123,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member) and u.server.id == element.auto_role.server.id: | ||||
|                     access = True | ||||
| @@ -138,6 +141,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member): | ||||
|                     access = True | ||||
| @@ -161,15 +166,30 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if u.id == element.id or permissions.is_member_moderator(member): | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == UserWarnings: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if u.id == element.user.id or permissions.is_member_moderator(member): | ||||
|                     access = True | ||||
|                     break | ||||
|  | ||||
|         elif type(element) == UserJoinedServer: | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if u.id == element.user.id or permissions.is_member_moderator(member): | ||||
|                     access = True | ||||
| @@ -179,6 +199,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if u.id == element.user.id or permissions.is_member_moderator(member): | ||||
|                     access = True | ||||
| @@ -188,6 +210,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if u.id == element.user.id or permissions.is_member_moderator(member): | ||||
|                     access = True | ||||
| @@ -197,6 +221,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_technician(member): | ||||
|                     access = True | ||||
| @@ -207,6 +233,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member) and u.server.id == element.server.id: | ||||
|                     access = True | ||||
| @@ -217,6 +245,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_moderator(member) and u.server.id == element.server.id: | ||||
|                     access = True | ||||
| @@ -226,6 +256,8 @@ class QueryABC(ObjectType): | ||||
|             for u in user.users: | ||||
|                 u: User = u | ||||
|                 guild = bot.get_guild(u.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     continue | ||||
|                 member = guild.get_member(u.discord_id) | ||||
|                 if permissions.is_member_technician(member): | ||||
|                     access = True | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "3" | ||||
|       "Micro": "8" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_graphql.filter" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -51,6 +51,8 @@ class AutoRoleRuleFilter(FilterABC): | ||||
|  | ||||
|             def get_role_name(x: AutoRoleRule): | ||||
|                 guild = self._bot.get_guild(x.auto_role.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     return False | ||||
|                 name = guild.get_role(x.role_id).name | ||||
|                 return name == self._role_name or self._role_name in name | ||||
|  | ||||
|   | ||||
| @@ -57,6 +57,8 @@ class ShortRoleNameFilter(FilterABC): | ||||
|  | ||||
|             def get_role_name(x: ShortRoleName): | ||||
|                 guild = self._bot.get_guild(x.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     return False | ||||
|                 name = guild.get_role(x.role_id).name | ||||
|                 return name == self._role_name or self._role_name in name | ||||
|  | ||||
|   | ||||
| @@ -80,6 +80,8 @@ class UserFilter(FilterABC): | ||||
|  | ||||
|             def _get_member(user: User): | ||||
|                 guild = self._bot.get_guild(user.server.discord_id) | ||||
|                 if guild is None: | ||||
|                     return False | ||||
|                 member = guild.get_member(user.discord_id) | ||||
|                 return member is not None and (member.name == self._name or self._name in member.name) | ||||
|  | ||||
|   | ||||
| @@ -44,7 +44,7 @@ class UserWarningFilter(FilterABC): | ||||
|  | ||||
|         if self._user is not None: | ||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.id) | ||||
|             query = query.where(lambda x: x.id in users) | ||||
|             query = query.where(lambda x: x.user.id in users) | ||||
|  | ||||
|         if self._description is not None: | ||||
|             query = query.where(lambda x: x.description == self._description or self._description in x.description) | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| type Level implements TableWithHistoryQuery { | ||||
|     id: ID | ||||
|     iconURL: String | ||||
|     name: String | ||||
|     color: String | ||||
|     minXp: Int | ||||
|   | ||||
| @@ -29,6 +29,9 @@ type Server implements TableWithHistoryQuery { | ||||
|     activeUserCount: Int | ||||
|     users(filter: UserFilter, page: Page, sort: Sort): [User] | ||||
|  | ||||
|     userWarningCount: Int | ||||
|     userWarnings(filter: UserWarningFilter, page: Page, sort: Sort): [UserWarning] | ||||
|  | ||||
|     achievementCount: Int | ||||
|     achievements(filter: AchievementFilter, page: Page, sort: Sort): [Achievement] | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,7 @@ type ServerConfig implements TableWithHistoryQuery { | ||||
|     defaultRoleId: String | ||||
|     shortRoleNameOnlySetHighestRole: Boolean | ||||
|     gameOfferNotificationChatId: String | ||||
|     resetMemberAfterRejoin: Boolean | ||||
|     featureFlagCount: Int | ||||
|     featureFlags: [FeatureFlag] | ||||
|  | ||||
| @@ -50,7 +51,7 @@ type ServerConfigHistory implements HistoryTableQuery { | ||||
|     loginMessageChannelId: String | ||||
|     defaultRoleId: String | ||||
|     shortRoleNameOnlySetHighestRole: Boolean | ||||
|     gameOfferNotificationChatId: String | ||||
|     resetMemberAfterRejoin: Boolean | ||||
|     featureFlagCount: Int | ||||
|     featureFlags: [FeatureFlag] | ||||
|  | ||||
| @@ -103,6 +104,7 @@ input ServerConfigInput { | ||||
|     defaultRoleId: String | ||||
|     shortRoleNameOnlySetHighestRole: Boolean | ||||
|     gameOfferNotificationChatId: String | ||||
|     resetMemberAfterRejoin: Boolean | ||||
|     featureFlags: [FeatureFlagInput] | ||||
|  | ||||
|     afkChannelIds: [String] | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_graphql.model" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_graphql.mutations" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -105,6 +105,11 @@ class ServerConfigMutation(QueryABC): | ||||
|             if "gameOfferNotificationChatId" in input | ||||
|             else server_config.game_offer_notification_chat_id | ||||
|         ) | ||||
|         server_config.reset_member_after_rejoin = ( | ||||
|             input["resetMemberAfterRejoin"] | ||||
|             if "resetMemberAfterRejoin" in input | ||||
|             else server_config.reset_member_after_rejoin | ||||
|         ) | ||||
|         server_config.feature_flags = ( | ||||
|             dict( | ||||
|                 zip( | ||||
|   | ||||
| @@ -7,6 +7,7 @@ from bot_data.model.short_role_name import ShortRoleName | ||||
| from bot_data.model.user_role_enum import UserRoleEnum | ||||
| from bot_graphql.abc.query_abc import QueryABC | ||||
| from bot_core.service.permission_service import PermissionService | ||||
| from modules.short_role_name.service.short_role_name_service import ShortRoleNameService | ||||
|  | ||||
|  | ||||
| class ShortRoleNameMutation(QueryABC): | ||||
| @@ -17,6 +18,7 @@ class ShortRoleNameMutation(QueryABC): | ||||
|         bot: DiscordBotServiceABC, | ||||
|         db: DatabaseContextABC, | ||||
|         permissions: PermissionService, | ||||
|         short_role_name_service: ShortRoleNameService, | ||||
|     ): | ||||
|         QueryABC.__init__(self, "ShortRoleNameMutation") | ||||
|  | ||||
| @@ -25,6 +27,7 @@ class ShortRoleNameMutation(QueryABC): | ||||
|         self._bot = bot | ||||
|         self._db = db | ||||
|         self._permissions = permissions | ||||
|         self._short_role_name_service = short_role_name_service | ||||
|  | ||||
|         self.set_field("createShortRoleName", self.resolve_create_short_role_name) | ||||
|         self.set_field("updateShortRoleName", self.resolve_update_short_role_name) | ||||
| @@ -79,6 +82,7 @@ class ShortRoleNameMutation(QueryABC): | ||||
|         short_role_name = self._short_role_names.get_short_role_name_by_id(id) | ||||
|         self._can_user_mutate_data(short_role_name.server, UserRoleEnum.admin) | ||||
|  | ||||
|         self._bot.loop.create_task(self._short_role_name_service.remove_short_role_from_members(short_role_name)) | ||||
|         self._short_role_names.delete_short_role_name(short_role_name) | ||||
|         self._db.save_changes() | ||||
|  | ||||
|   | ||||
| @@ -86,5 +86,9 @@ class UserMutation(QueryABC): | ||||
|                 continue | ||||
|  | ||||
|             member = self._bot.get_guild(user.server.discord_id).get_member(user.discord_id) | ||||
|             author = self._users.get_user_by_id(int(warning["author"])) | ||||
|             if "author" not in warning: | ||||
|                 author = Route.get_user().users.where(lambda u: u.server.id == user.server.id).single() | ||||
|             else: | ||||
|                 author = self._users.get_user_by_id(int(warning["author"])) | ||||
|  | ||||
|             self._user_warning_service.add_warnings(member, warning["description"], author.discord_id) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_graphql.queries" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "bot_graphql.queries.discord" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
|  | ||||
| from bot_data.model.level import Level | ||||
| from bot_data.model.level_history import LevelHistory | ||||
| from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC | ||||
|  | ||||
| @@ -9,33 +8,10 @@ class LevelQuery(DataQueryWithHistoryABC): | ||||
|     def __init__(self, db: DatabaseContextABC): | ||||
|         DataQueryWithHistoryABC.__init__(self, "Level", "LevelsHistory", LevelHistory, db) | ||||
|  | ||||
|         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 | ||||
|         self.set_field("id", lambda x, *_: x.id) | ||||
|         self.set_field("iconURL", lambda x, *_: x.icon_url) | ||||
|         self.set_field("name", lambda x, *_: x.name) | ||||
|         self.set_field("color", lambda x, *_: x.color) | ||||
|         self.set_field("minXp", lambda x, *_: x.min_xp) | ||||
|         self.set_field("permissions", lambda x, *_: x.permissions) | ||||
|         self.set_field("server", lambda x, *_: x.server) | ||||
|   | ||||
| @@ -37,6 +37,7 @@ class ServerConfigQuery(DataQueryWithHistoryABC): | ||||
|             "gameOfferNotificationChatId", | ||||
|             lambda config, *_: config.game_offer_notification_chat_id, | ||||
|         ) | ||||
|         self.set_field("resetMemberAfterRejoin", lambda config, *_: config.reset_member_after_rejoin) | ||||
|         self.add_collection( | ||||
|             "featureFlag", | ||||
|             lambda config, *_: List( | ||||
|   | ||||
| @@ -8,7 +8,6 @@ from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC | ||||
| from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | ||||
| from bot_data.abc.client_repository_abc import ClientRepositoryABC | ||||
| from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC | ||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC | ||||
| from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC | ||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||
| from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC | ||||
| @@ -17,6 +16,7 @@ from bot_data.abc.user_joined_voice_channel_repository_abc import ( | ||||
|     UserJoinedVoiceChannelRepositoryABC, | ||||
| ) | ||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||
| from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC | ||||
| from bot_data.model.server import Server | ||||
| from bot_data.model.server_config import ServerConfig | ||||
| from bot_data.model.server_history import ServerHistory | ||||
| @@ -28,7 +28,9 @@ from bot_graphql.filter.level_filter import LevelFilter | ||||
| from bot_graphql.filter.scheduled_event_filter import ScheduledEventFilter | ||||
| from bot_graphql.filter.short_role_name_filter import ShortRoleNameFilter | ||||
| from bot_graphql.filter.user_filter import UserFilter | ||||
| from bot_graphql.filter.user_warning_filter import UserWarningFilter | ||||
| from bot_graphql.model.server_statistics import ServerStatistics | ||||
| from modules.level.service.level_service import LevelService | ||||
|  | ||||
|  | ||||
| class ServerQuery(DataQueryWithHistoryABC): | ||||
| @@ -39,7 +41,7 @@ class ServerQuery(DataQueryWithHistoryABC): | ||||
|         db: DatabaseContextABC, | ||||
|         auto_roles: AutoRoleRepositoryABC, | ||||
|         clients: ClientRepositoryABC, | ||||
|         levels: LevelRepositoryABC, | ||||
|         levels: LevelService, | ||||
|         game_servers: GameServerRepositoryABC, | ||||
|         users: UserRepositoryABC, | ||||
|         ujs: UserJoinedServerRepositoryABC, | ||||
| @@ -48,6 +50,7 @@ class ServerQuery(DataQueryWithHistoryABC): | ||||
|         short_role_names: ShortRoleNameRepositoryABC, | ||||
|         scheduled_events: ScheduledEventRepositoryABC, | ||||
|         server_configs: ServerConfigRepositoryABC, | ||||
|         user_warnings: UserWarningsRepositoryABC, | ||||
|     ): | ||||
|         DataQueryWithHistoryABC.__init__(self, "Server", "ServersHistory", ServerHistory, db) | ||||
|  | ||||
| @@ -77,7 +80,7 @@ class ServerQuery(DataQueryWithHistoryABC): | ||||
|         ) | ||||
|         self.add_collection( | ||||
|             "level", | ||||
|             lambda server, *_: self._levels.get_levels_by_server_id(server.id), | ||||
|             lambda server, *_: self._levels.get_levels_by_server_id(server.id).order_by_descending(lambda x: x.min_xp), | ||||
|             LevelFilter, | ||||
|         ) | ||||
|         self.set_field( | ||||
| @@ -89,6 +92,11 @@ class ServerQuery(DataQueryWithHistoryABC): | ||||
|             lambda server, *_: self._users.get_users_with_activity_by_server_id(server.id), | ||||
|             UserFilter, | ||||
|         ) | ||||
|         self.add_collection( | ||||
|             "userWarning", | ||||
|             lambda server, *_: user_warnings.get_user_warnings_by_server_id(server.id), | ||||
|             UserWarningFilter, | ||||
|         ) | ||||
|         self.add_collection( | ||||
|             "gameServer", | ||||
|             lambda server, *_: game_servers.get_game_servers_by_server_id(server.id), | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "modules.achievements" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     "Version": { | ||||
|       "Major": "1", | ||||
|       "Minor": "2", | ||||
|       "Micro": "3" | ||||
|       "Micro": "8" | ||||
|     }, | ||||
|     "Author": "Sven Heidemann", | ||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||
|   | ||||
| @@ -15,7 +15,7 @@ __title__ = "modules.achievements.commands" | ||||
| __author__ = "Sven Heidemann" | ||||
| __license__ = "MIT" | ||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||
| __version__ = "1.2.3" | ||||
| __version__ = "1.2.8" | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
| @@ -23,4 +23,4 @@ from collections import namedtuple | ||||
| # imports | ||||
|  | ||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="3") | ||||
| version_info = VersionInfo(major="1", minor="2", micro="8") | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user