forked from sh-edraft.de/sh_discord_bot
Compare commits
61 Commits
Author | SHA1 | Date | |
---|---|---|---|
f8992638d4 | |||
77e4491e90 | |||
523eb23f09 | |||
6865953433 | |||
d3dd825358 | |||
abac507e87 | |||
359a614a1a | |||
f2e6be530b | |||
2df4f90802 | |||
869439d3b8 | |||
36a8a5be3c | |||
8966bded81 | |||
c7c60edbd7 | |||
17befd9f05 | |||
eb3bdac162 | |||
b75777a339 | |||
5795028fdb | |||
8afc414d8b | |||
a23815998c | |||
97e4f8ec29 | |||
21c34436b9 | |||
b35b023b02 | |||
9daa0b1c54 | |||
d0ed413150 | |||
fa98f08161 | |||
f150df2dfd | |||
901aa4e1a5 | |||
7c0e34e1f8 | |||
bf5003f100 | |||
9f4c6d45c6 | |||
04e8e64003 | |||
1c3ec3c7e7 | |||
1a8c74d9e0 | |||
676d718fc2 | |||
11791ccf98 | |||
05fbe72304 | |||
b8874a6eab | |||
03497b6d5a | |||
5b1a98ad5c | |||
63ff8f54fa | |||
cb1ebeeb0c | |||
54db704044 | |||
d5a1c15db3 | |||
fa50123d3b | |||
e2749f6a81 | |||
12cd5c9045 | |||
6e5e5d4550 | |||
890cb6f6b5 | |||
ac238b360a | |||
8b55db172a | |||
7496a17cfa | |||
0dbf33a39f | |||
a939c741cb | |||
a4dc66396e | |||
a8b6989d27 | |||
51fec48cda | |||
4b8af2aef4 | |||
b936e569aa | |||
709767c3a0 | |||
40beb3711a | |||
4cd41c4b26 |
@@ -6,6 +6,7 @@
|
||||
"bot-core": "src/bot_core/bot-core.json",
|
||||
"bot-data": "src/bot_data/bot-data.json",
|
||||
"admin": "src/modules/admin/admin.json",
|
||||
"auto-role": "src/modules/auto_role/auto-role.json",
|
||||
"base": "src/modules/base/base.json",
|
||||
"boot-log": "src/modules/boot_log/boot-log.json",
|
||||
"database": "src/modules/database/database.json",
|
||||
@@ -15,7 +16,11 @@
|
||||
"Scripts": {
|
||||
"prod": "export KDB_ENVIRONMENT=production; export KDB_NAME=KDB-Prod; cpl start;",
|
||||
"stage": "export KDB_ENVIRONMENT=staging; export KDB_NAME=KDB-Stage; cpl start;",
|
||||
"dev": "export KDB_ENVIRONMENT=development; export KDB_NAME=KDB-Dev; cpl start;"
|
||||
"dev": "export KDB_ENVIRONMENT=development; export KDB_NAME=KDB-Dev; cpl start;",
|
||||
|
||||
"build-docker": "cpl b; docker-compose down; docker build -t kdb .",
|
||||
"compose": "docker-compose up -d",
|
||||
"docker": "cpl build-docker; cpl compose;"
|
||||
}
|
||||
}
|
||||
}
|
64
docker-compose.yml
Normal file
64
docker-compose.yml
Normal file
@@ -0,0 +1,64 @@
|
||||
version: "3.9"
|
||||
|
||||
volumes:
|
||||
kdb_prod_1:
|
||||
kdb_staging_1:
|
||||
kdb_db_1:
|
||||
kdb_db_2:
|
||||
|
||||
services:
|
||||
kdb_prod_1:
|
||||
image: kdb/kdb:0.2.1
|
||||
container_name: kdb_prod_1
|
||||
depends_on:
|
||||
- kdb_db_1
|
||||
volumes:
|
||||
- kdb_prod_1:/app
|
||||
environment:
|
||||
KDB_ENVIRONMENT: "production"
|
||||
KDB_TOKEN: ""
|
||||
KDB_PREFIX: "!k "
|
||||
restart: 'no'
|
||||
|
||||
kdb_staging_1:
|
||||
image: kdb/kdb:0.2.1
|
||||
container_name: kdb_staging_1
|
||||
depends_on:
|
||||
- kdb_db_1
|
||||
volumes:
|
||||
- kdb_staging_1:/app
|
||||
environment:
|
||||
KDB_ENVIRONMENT: "staging"
|
||||
KDB_TOKEN: ""
|
||||
KDB_PREFIX: "!kt "
|
||||
restart: 'no'
|
||||
|
||||
kdb_db_1:
|
||||
image: mysql:latest
|
||||
container_name: kdb_db_1
|
||||
command: mysqld --default-authentication-plugin=mysql_native_password
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "kd_kdb"
|
||||
MYSQL_USER: "kd_kdb"
|
||||
MYSQL_PASSWORD: "kd_kdb"
|
||||
MYSQL_DATABASE: "kd_kdb"
|
||||
ports:
|
||||
- "3307:3306"
|
||||
volumes:
|
||||
- kdb_db_1:/var/lib/mysql
|
||||
|
||||
kdb_db_2:
|
||||
image: mysql:latest
|
||||
container_name: kdb_db_2
|
||||
command: mysqld --default-authentication-plugin=mysql_native_password
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "kd_kdb"
|
||||
MYSQL_USER: "kd_kdb"
|
||||
MYSQL_PASSWORD: "kd_kdb"
|
||||
MYSQL_DATABASE: "kd_kdb"
|
||||
ports:
|
||||
- "3308:3306"
|
||||
volumes:
|
||||
- kdb_db_2:/var/lib/mysql
|
18
dockerfile
Normal file
18
dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM python:3.10.7-bullseye
|
||||
|
||||
WORKDIR /app
|
||||
COPY ./dist/bot/build/ .
|
||||
|
||||
RUN pip install cpl-core --extra-index-url https://pip.sh-edraft.de
|
||||
RUN pip install cpl-discord --extra-index-url https://pip.sh-edraft.de
|
||||
RUN pip install cpl-query --extra-index-url https://pip.sh-edraft.de
|
||||
RUN pip install cpl-translation --extra-index-url https://pip.sh-edraft.de
|
||||
RUN apt-get update -y
|
||||
RUN apt-get install nano -y
|
||||
|
||||
ENV KDB_TOKEN=""
|
||||
ENV KDB_PREFIX="!kdb "
|
||||
ENV KDB_ENVIRONMENT="production"
|
||||
|
||||
CMD [ "bash", "/app/bot/bot"]
|
@@ -15,7 +15,7 @@ __title__ = 'bot'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -1,6 +1,4 @@
|
||||
from typing import Optional, Type
|
||||
|
||||
from cpl_core.configuration import ConfigurationABC, ConfigurationModelABC
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.console import Console
|
||||
from cpl_core.dependency_injection import ServiceProviderABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
@@ -9,21 +7,14 @@ from cpl_discord.configuration import DiscordBotSettings
|
||||
from cpl_discord.service import DiscordBotServiceABC, DiscordBotService
|
||||
from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings
|
||||
|
||||
from bot_core.configuration.bot_settings import BotSettings
|
||||
from bot_core.configuration.server_settings import ServerSettings
|
||||
from modules.base.configuration.base_server_settings import BaseServerSettings
|
||||
from modules.base.configuration.base_settings import BaseSettings
|
||||
from modules.boot_log.configuration.boot_log_server_settings import BootLogServerSettings
|
||||
from modules.boot_log.configuration.boot_log_settings import BootLogSettings
|
||||
from modules.permission.configuration.permission_server_settings import PermissionServerSettings
|
||||
from modules.permission.configuration.permission_settings import PermissionSettings
|
||||
|
||||
|
||||
class Application(DiscordBotApplicationABC):
|
||||
|
||||
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||
DiscordBotApplicationABC.__init__(self, config, services)
|
||||
|
||||
self._services = services
|
||||
|
||||
# cpl-core
|
||||
self._logger: LoggerABC = services.get_service(LoggerABC)
|
||||
# cpl-discord
|
||||
@@ -31,33 +22,27 @@ class Application(DiscordBotApplicationABC):
|
||||
self._bot_settings: DiscordBotSettings = config.get_configuration(DiscordBotSettings)
|
||||
# cpl-translation
|
||||
self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC)
|
||||
self._translate: TranslatePipe = services.get_service(TranslatePipe)
|
||||
self._t: TranslatePipe = services.get_service(TranslatePipe)
|
||||
|
||||
def _configure_settings_with_servers(self, settings: Type, server_settings: Type):
|
||||
settings: Optional[settings] = self._configuration.get_configuration(settings)
|
||||
if settings is None:
|
||||
return
|
||||
|
||||
for server in settings.servers:
|
||||
self._logger.trace(__name__, f'Saved config: {type(server).__name__}_{server.id}')
|
||||
self._configuration.add_configuration(f'{type(server).__name__}_{server.id}', server)
|
||||
self._is_stopping = False
|
||||
|
||||
async def configure(self):
|
||||
self._translation.load_by_settings(self._configuration.get_configuration(TranslationSettings))
|
||||
self._configure_settings_with_servers(BotSettings, ServerSettings)
|
||||
self._configure_settings_with_servers(BaseSettings, BaseServerSettings)
|
||||
self._configure_settings_with_servers(BootLogSettings, BootLogServerSettings)
|
||||
self._configure_settings_with_servers(PermissionSettings, PermissionServerSettings)
|
||||
|
||||
async def main(self):
|
||||
try:
|
||||
self._logger.debug(__name__, f'Starting...\n')
|
||||
self._logger.debug(__name__, f'Starting...')
|
||||
self._logger.trace(__name__, f'Try to start {DiscordBotService.__name__}')
|
||||
await self._bot.start_async()
|
||||
await self._bot.stop_async()
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, 'Start failed', e)
|
||||
|
||||
async def stop_async(self):
|
||||
if self._is_stopping:
|
||||
return
|
||||
|
||||
self._is_stopping = True
|
||||
try:
|
||||
self._logger.trace(__name__, f'Try to stop {DiscordBotService.__name__}')
|
||||
await self._bot.close()
|
||||
@@ -68,4 +53,4 @@ class Application(DiscordBotApplicationABC):
|
||||
Console.write_line()
|
||||
|
||||
def is_restart(self):
|
||||
return True if self._configuration.get_configuration('IS_RESTART') == 'true' else False
|
||||
return True if self._configuration.get_configuration('IS_RESTART') == 'true' else False#
|
||||
|
@@ -2,9 +2,9 @@
|
||||
"ProjectSettings": {
|
||||
"Name": "bot",
|
||||
"Version": {
|
||||
"Major": "1",
|
||||
"Minor": "0",
|
||||
"Micro": "0.dev3"
|
||||
"Major": "0",
|
||||
"Minor": "2",
|
||||
"Micro": "3"
|
||||
},
|
||||
"Author": "Sven Heidemann",
|
||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||
@@ -16,13 +16,13 @@
|
||||
"LicenseName": "MIT",
|
||||
"LicenseDescription": "MIT, see LICENSE for more details.",
|
||||
"Dependencies": [
|
||||
"cpl-core>=2022.7.0.post4",
|
||||
"cpl-translation==2022.7.0.post2",
|
||||
"cpl-query==2022.7.0",
|
||||
"cpl-discord==2022.7.0.post4"
|
||||
"cpl-core==2022.10.0.post6",
|
||||
"cpl-translation==2022.10.0",
|
||||
"cpl-query==2022.10.0",
|
||||
"cpl-discord==2022.10.0.post5"
|
||||
],
|
||||
"DevDependencies": [
|
||||
"cpl-cli>=2022.7.0.post2"
|
||||
"cpl-cli==2022.10.0"
|
||||
],
|
||||
"PythonVersion": ">=3.10.4",
|
||||
"PythonPath": {
|
||||
@@ -48,11 +48,13 @@
|
||||
"../bot_core/bot-core.json",
|
||||
"../bot_data/bot-data.json",
|
||||
"../modules/base/base.json",
|
||||
"../modules/admin/admin.json",
|
||||
"../modules/auto_role/auto-role.json",
|
||||
"../modules/base/base.json",
|
||||
"../modules/boot_log/boot-log.json",
|
||||
"../modules/database/database.json",
|
||||
"../modules/permission/permission.json",
|
||||
"../modules/admin/admin.json",
|
||||
"../modules/moderator/moderator.json"
|
||||
"../modules/moderator/moderator.json",
|
||||
"../modules/permission/permission.json"
|
||||
]
|
||||
}
|
||||
}
|
@@ -7,10 +7,30 @@
|
||||
},
|
||||
"LoggingSettings": {
|
||||
"Path": "logs/",
|
||||
"Filename": "log_dev.log",
|
||||
"Filename": "bot.log",
|
||||
"ConsoleLogLevel": "DEBUG",
|
||||
"FileLogLevel": "DEBUG"
|
||||
},
|
||||
"BotLoggingSettings": {
|
||||
"Command": {
|
||||
"Path": "logs/",
|
||||
"Filename": "commands.log",
|
||||
"ConsoleLogLevel": "DEBUG",
|
||||
"FileLogLevel": "DEBUG"
|
||||
},
|
||||
"Database": {
|
||||
"Path": "logs/",
|
||||
"Filename": "database.log",
|
||||
"ConsoleLogLevel": "DEBUG",
|
||||
"FileLogLevel": "DEBUG"
|
||||
},
|
||||
"Message": {
|
||||
"Path": "logs/",
|
||||
"Filename": "message.log",
|
||||
"ConsoleLogLevel": "DEBUG",
|
||||
"FileLogLevel": "DEBUG"
|
||||
}
|
||||
},
|
||||
"Translation": {
|
||||
"DefaultLanguage": "de",
|
||||
"Languages": [
|
||||
@@ -29,7 +49,8 @@
|
||||
240160344557879316,
|
||||
236592458664902657
|
||||
],
|
||||
"DeployFilesPath": "../../deploy"
|
||||
"WaitForRestart": 4,
|
||||
"WaitForShutdown": 4
|
||||
},
|
||||
"Base": {
|
||||
"910199451145076828": {
|
||||
|
86
src/bot/config/appsettings.edrafts-pc-ubuntu.json
Normal file
86
src/bot/config/appsettings.edrafts-pc-ubuntu.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"TimeFormatSettings": {
|
||||
"DateFormat": "%Y-%m-%d",
|
||||
"TimeFormat": "%H:%M:%S",
|
||||
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
|
||||
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
|
||||
},
|
||||
"LoggingSettings": {
|
||||
"Path": "logs/",
|
||||
"Filename": "bot.log",
|
||||
"ConsoleLogLevel": "TRACE",
|
||||
"FileLogLevel": "TRACE"
|
||||
},
|
||||
"BotLoggingSettings": {
|
||||
"Command": {
|
||||
"Path": "logs/",
|
||||
"Filename": "commands.log",
|
||||
"ConsoleLogLevel": "DEBUG",
|
||||
"FileLogLevel": "TRACE"
|
||||
},
|
||||
"Database": {
|
||||
"Path": "logs/",
|
||||
"Filename": "database.log",
|
||||
"ConsoleLogLevel": "DEBUG",
|
||||
"FileLogLevel": "TRACE"
|
||||
},
|
||||
"Message": {
|
||||
"Path": "logs/",
|
||||
"Filename": "message.log",
|
||||
"ConsoleLogLevel": "DEBUG",
|
||||
"FileLogLevel": "TRACE"
|
||||
}
|
||||
},
|
||||
"DatabaseSettings": {
|
||||
"Host": "localhost",
|
||||
"User": "kd_kdb",
|
||||
"Password": "VGpZcihrb0N2T2MyZUlURQ==",
|
||||
"Database": "keksdose_bot_dev",
|
||||
"Charset": "utf8mb4",
|
||||
"UseUnicode": "true",
|
||||
"Buffered": "true",
|
||||
"AuthPlugin": "mysql_native_password"
|
||||
},
|
||||
"DiscordBot": {
|
||||
"Token": "OTk4MTYwNDI3Njg5MTgxMjM3.GI7h67.BqD6Lu1Tz0MuG8iktYrcLnHi1pNozyMiWFGTKI",
|
||||
"Prefix": "!ke "
|
||||
},
|
||||
"Bot": {
|
||||
"910199451145076828": {
|
||||
"MessageDeleteTimer": 2
|
||||
},
|
||||
"Technicians": [
|
||||
240160344557879316
|
||||
],
|
||||
"WaitForRestart": 4,
|
||||
"WaitForShutdown": 4
|
||||
},
|
||||
"Base": {
|
||||
"910199451145076828": {
|
||||
"MaxVoiceStateHours": 24,
|
||||
"XpPerMessage": 2,
|
||||
"XpPerOntimeHour": 4,
|
||||
"AFKChannelIds": [
|
||||
910199452915093593,
|
||||
910199452915093594
|
||||
],
|
||||
"AFKCommandChannelId": 910199452915093594,
|
||||
"HelpCommandReferenceUrl": "https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot/wiki/Befehle"
|
||||
}
|
||||
},
|
||||
"BootLog": {
|
||||
"910199451145076828": {
|
||||
"LoginMessageChannelId": "910199452915093588"
|
||||
}
|
||||
},
|
||||
"Permission": {
|
||||
"910199451145076828": {
|
||||
"AdminRoleIds": [
|
||||
925072155203477584
|
||||
],
|
||||
"ModeratorRoleIds": [
|
||||
925072209884635167
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,9 +6,29 @@
|
||||
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
|
||||
},
|
||||
"LoggingSettings": {
|
||||
"Path": "logs/",
|
||||
"Filename": "log_$start_time.log",
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "bot.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "WARN"
|
||||
},
|
||||
"BotLoggingSettings": {
|
||||
"Command": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "commands.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "WARN"
|
||||
},
|
||||
"Database": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "database.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "WARN"
|
||||
},
|
||||
"Message": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "message.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "WARN"
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,17 +6,48 @@
|
||||
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
|
||||
},
|
||||
"LoggingSettings": {
|
||||
"Path": "logs/",
|
||||
"Filename": "log_$start_time.log",
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "bot.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "INFO"
|
||||
},
|
||||
"BotLoggingSettings": {
|
||||
"Command": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "commands.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "INFO"
|
||||
},
|
||||
"Database": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "database.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "INFO"
|
||||
},
|
||||
"Message": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "message.log",
|
||||
"ConsoleLogLevel": "ERROR",
|
||||
"FileLogLevel": "INFO"
|
||||
}
|
||||
},
|
||||
"Translation": {
|
||||
"DefaultLanguage": "de",
|
||||
"Languages": [
|
||||
"de"
|
||||
]
|
||||
},
|
||||
"DatabaseSettings": {
|
||||
"Host": "kdb_db_1",
|
||||
"User": "kd_kdb",
|
||||
"Password": "a2Rfa2Ri",
|
||||
"Database": "kd_kdb",
|
||||
"Port": "3306",
|
||||
"Charset": "utf8mb4",
|
||||
"UseUnicode": "true",
|
||||
"Buffered": "true",
|
||||
"AuthPlugin": "mysql_native_password"
|
||||
},
|
||||
"Bot": {
|
||||
"650366049023295514": {
|
||||
"MessageDeleteTimer": 2
|
||||
@@ -28,7 +59,8 @@
|
||||
240160344557879316,
|
||||
236592458664902657
|
||||
],
|
||||
"DeployFilesPath": "../../"
|
||||
"WaitForRestart": 4,
|
||||
"WaitForShutdown": 4
|
||||
},
|
||||
"Base": {
|
||||
"650366049023295514": {
|
||||
|
@@ -6,17 +6,48 @@
|
||||
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
|
||||
},
|
||||
"LoggingSettings": {
|
||||
"Path": "logs/",
|
||||
"Filename": "log_staging_$start_time.log",
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "bot.log",
|
||||
"ConsoleLogLevel": "INFO",
|
||||
"FileLogLevel": "DEBUG"
|
||||
},
|
||||
"BotLoggingSettings": {
|
||||
"Command": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "commands.log",
|
||||
"ConsoleLogLevel": "INFO",
|
||||
"FileLogLevel": "DEBUG"
|
||||
},
|
||||
"Database": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "database.log",
|
||||
"ConsoleLogLevel": "INFO",
|
||||
"FileLogLevel": "DEBUG"
|
||||
},
|
||||
"Message": {
|
||||
"Path": "logs/$date_now/",
|
||||
"Filename": "message.log",
|
||||
"ConsoleLogLevel": "INFO",
|
||||
"FileLogLevel": "DEBUG"
|
||||
}
|
||||
},
|
||||
"Translation": {
|
||||
"DefaultLanguage": "de",
|
||||
"Languages": [
|
||||
"de"
|
||||
]
|
||||
},
|
||||
"DatabaseSettings": {
|
||||
"Host": "kdb_db_2",
|
||||
"User": "kd_kdb",
|
||||
"Password": "a2Rfa2Ri",
|
||||
"Database": "kd_kdb",
|
||||
"Port": "3306",
|
||||
"Charset": "utf8mb4",
|
||||
"UseUnicode": "true",
|
||||
"Buffered": "true",
|
||||
"AuthPlugin": "mysql_native_password"
|
||||
},
|
||||
"Bot": {
|
||||
"910199451145076828": {
|
||||
"MessageDeleteTimer": 4
|
||||
@@ -25,7 +56,8 @@
|
||||
240160344557879316,
|
||||
236592458664902657
|
||||
],
|
||||
"DeployFilesPath": "../../"
|
||||
"WaitForRestart": 4,
|
||||
"WaitForShutdown": 4
|
||||
},
|
||||
"Base": {
|
||||
"910199451145076828": {
|
||||
|
14
src/bot/config/feature-flags.json
Normal file
14
src/bot/config/feature-flags.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"FeatureFlags": {
|
||||
"AdminModule": true,
|
||||
"AutoRoleModule": true,
|
||||
"BaseModule": true,
|
||||
"BootLogModule": true,
|
||||
"CoreModule": true,
|
||||
"CoreExtensionModule": true,
|
||||
"DatabaseModule": true,
|
||||
"ModeratorModule": true,
|
||||
"PermissionModule": true,
|
||||
"PresenceModule": true
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import traceback
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.application import ApplicationBuilder
|
||||
@@ -8,6 +9,8 @@ from bot.application import Application
|
||||
from bot.startup import Startup
|
||||
from bot.startup_discord_extension import StartupDiscordExtension
|
||||
from bot.startup_migration_extension import StartupMigrationExtension
|
||||
from bot.startup_module_extension import StartupModuleExtension
|
||||
from bot.startup_settings_extension import StartupSettingsExtension
|
||||
from modules.boot_log.boot_log_extension import BootLogExtension
|
||||
from modules.database.database_extension import DatabaseExtension
|
||||
|
||||
@@ -18,16 +21,21 @@ class Program:
|
||||
self.app: Optional[Application] = None
|
||||
|
||||
async def start(self):
|
||||
app_builder = ApplicationBuilder(Application)
|
||||
app_builder.use_extension(StartupDiscordExtension)
|
||||
app_builder.use_extension(StartupMigrationExtension)
|
||||
app_builder.use_extension(BootLogExtension)
|
||||
app_builder.use_extension(DatabaseExtension)
|
||||
app_builder.use_startup(Startup)
|
||||
# discord extension has to be loaded before modules (modules depends on discord stuff)
|
||||
app_builder = ApplicationBuilder(Application) \
|
||||
.use_extension(StartupSettingsExtension) \
|
||||
.use_extension(StartupDiscordExtension) \
|
||||
.use_extension(StartupModuleExtension) \
|
||||
.use_extension(StartupMigrationExtension) \
|
||||
.use_extension(BootLogExtension) \
|
||||
.use_extension(DatabaseExtension) \
|
||||
.use_startup(Startup)
|
||||
self.app: Application = await app_builder.build_async()
|
||||
await self.app.run_async()
|
||||
|
||||
async def stop(self):
|
||||
if self.app is None:
|
||||
return
|
||||
await self.app.stop_async()
|
||||
|
||||
|
||||
@@ -38,12 +46,12 @@ def main():
|
||||
except KeyboardInterrupt:
|
||||
asyncio.run(program.stop())
|
||||
except Exception as e:
|
||||
Console.error(f'[ ERROR ] [ {__name__} ]: Cannot start the bot', str(e))
|
||||
Console.error(f'[ ERROR ] [ {__name__} ]: Cannot start the bot', f'{e} -> {traceback.format_exc()}')
|
||||
finally:
|
||||
try:
|
||||
asyncio.run(program.stop())
|
||||
except Exception as e:
|
||||
Console.error(f'[ ERROR ] [ {__name__} ]: Cannot stop the bot', str(e))
|
||||
Console.error(f'[ ERROR ] [ {__name__} ]: Cannot stop the bot', f'{e} -> {traceback.format_exc()}')
|
||||
|
||||
if program.app is not None and program.app.is_restart():
|
||||
del program
|
||||
|
32
src/bot/module_list.py
Normal file
32
src/bot/module_list.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.core_extension.core_extension_module import CoreExtensionModule
|
||||
from bot_core.core_module import CoreModule
|
||||
from bot_data.data_module import DataModule
|
||||
from modules.admin.admin_module import AdminModule
|
||||
from modules.auto_role.auto_role_module import AutoRoleModule
|
||||
from modules.base.base_module import BaseModule
|
||||
from modules.boot_log.boot_log_module import BootLogModule
|
||||
from modules.database.database_module import DatabaseModule
|
||||
from modules.moderator.moderator_module import ModeratorModule
|
||||
from modules.permission.permission_module import PermissionModule
|
||||
|
||||
|
||||
class ModuleList:
|
||||
|
||||
@staticmethod
|
||||
def get_modules():
|
||||
# core modules (modules out of modules folder) should be loaded first!
|
||||
return List(type, [
|
||||
CoreModule, # has to be first!
|
||||
DataModule,
|
||||
AdminModule,
|
||||
AutoRoleModule,
|
||||
BaseModule,
|
||||
DatabaseModule,
|
||||
ModeratorModule,
|
||||
PermissionModule,
|
||||
# has to be last!
|
||||
BootLogModule,
|
||||
CoreExtensionModule,
|
||||
])
|
@@ -1,35 +1,21 @@
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.application import StartupABC
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.database import DatabaseSettings
|
||||
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.dependency_injection import ServiceProviderABC
|
||||
from cpl_core.environment import ApplicationEnvironment
|
||||
from cpl_core.logging import LoggerABC
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe
|
||||
from bot_core.service.client_utils_service import ClientUtilsService
|
||||
from bot_core.service.message_service import MessageService
|
||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
||||
from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
|
||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_core.logging.message_logger import MessageLogger
|
||||
from bot_data.db_context import DBContext
|
||||
from bot_data.service.client_repository_service import ClientRepositoryService
|
||||
from bot_data.service.known_user_repository_service import KnownUserRepositoryService
|
||||
from bot_data.service.server_repository_service import ServerRepositoryService
|
||||
from bot_data.service.user_joined_server_repository_service import UserJoinedServerRepositoryService
|
||||
from bot_data.service.user_joined_voice_channel_service import UserJoinedVoiceChannelRepositoryService
|
||||
from bot_data.service.user_repository_service import UserRepositoryService
|
||||
from modules.base.abc.base_helper_abc import BaseHelperABC
|
||||
from modules.base.service.base_helper_service import BaseHelperService
|
||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||
from modules.permission.service.permission_service import PermissionService
|
||||
|
||||
|
||||
class Startup(StartupABC):
|
||||
@@ -39,44 +25,32 @@ class Startup(StartupABC):
|
||||
self._start_time = datetime.now()
|
||||
|
||||
self._config: Optional[ConfigurationABC] = None
|
||||
self._feature_flags: Optional[FeatureFlagsSettings] = None
|
||||
|
||||
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
|
||||
environment.set_working_directory(os.path.dirname(os.path.realpath(__file__)))
|
||||
configuration.add_environment_variables('KDB_')
|
||||
configuration.add_environment_variables('DISCORD_')
|
||||
|
||||
configuration.add_json_file(f'config/appsettings.json', optional=False)
|
||||
configuration.add_json_file(f'config/appsettings.{environment.environment_name}.json', optional=True)
|
||||
configuration.add_json_file(f'config/appsettings.{environment.host_name}.json', optional=True)
|
||||
|
||||
configuration.add_configuration('Startup_StartTime', str(self._start_time))
|
||||
|
||||
self._config = configuration
|
||||
self._feature_flags = configuration.get_configuration(FeatureFlagsSettings)
|
||||
return configuration
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
|
||||
services.add_logging()
|
||||
services.add_translation()
|
||||
if self._feature_flags.get_flag(FeatureFlagsEnum.core_module):
|
||||
# custom logging
|
||||
services.add_singleton(CustomFileLoggerABC, CommandLogger)
|
||||
services.add_singleton(CustomFileLoggerABC, DatabaseLogger)
|
||||
services.add_singleton(CustomFileLoggerABC, MessageLogger)
|
||||
|
||||
services.add_translation()
|
||||
services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings))
|
||||
|
||||
# general services
|
||||
services.add_transient(BaseHelperABC, BaseHelperService)
|
||||
services.add_transient(MessageServiceABC, MessageService)
|
||||
services.add_transient(ClientUtilsServiceABC, ClientUtilsService)
|
||||
provider = services.build_service_provider()
|
||||
# instantiate custom logger
|
||||
for c in CustomFileLoggerABC.__subclasses__():
|
||||
i: LoggerABC = provider.get_service(c)
|
||||
|
||||
# pipes
|
||||
services.add_transient(DateTimeOffsetPipe)
|
||||
|
||||
# module services
|
||||
services.add_singleton(PermissionServiceABC, PermissionService)
|
||||
logger: LoggerABC = provider.get_service(LoggerABC)
|
||||
for flag in [f for f in FeatureFlagsEnum]:
|
||||
logger.debug(__name__, f'Loaded feature-flag: {flag} = {self._feature_flags.get_flag(flag)}')
|
||||
|
||||
# data services
|
||||
services.add_transient(ServerRepositoryABC, ServerRepositoryService)
|
||||
services.add_transient(UserRepositoryABC, UserRepositoryService)
|
||||
services.add_transient(ClientRepositoryABC, ClientRepositoryService)
|
||||
services.add_transient(KnownUserRepositoryABC, KnownUserRepositoryService)
|
||||
services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService)
|
||||
services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService)
|
||||
|
||||
return services.build_service_provider()
|
||||
return provider
|
||||
|
@@ -3,26 +3,6 @@ from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord import get_discord_collection
|
||||
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
|
||||
|
||||
from modules.admin.command.deploy_command import DeployCommand
|
||||
from modules.admin.command.restart_command import RestartCommand
|
||||
from modules.admin.command.shutdown_command import ShutdownCommand
|
||||
from modules.base.command.afk_command import AFKCommand
|
||||
from modules.base.command.help_command import HelpCommand
|
||||
from modules.base.command.info_command import InfoCommand
|
||||
from modules.base.command.ping_command import PingCommand
|
||||
from modules.base.events.base_on_command_error_event import BaseOnCommandErrorEvent
|
||||
from modules.moderator.command.purge_command import PurgeCommand
|
||||
from modules.base.command.user_info_command import UserInfoCommand
|
||||
from modules.base.events.base_on_member_join_event import BaseOnMemberJoinEvent
|
||||
from modules.base.events.base_on_member_remove_event import BaseOnMemberRemoveEvent
|
||||
from modules.base.events.base_on_message_event import BaseOnMessageEvent
|
||||
from modules.base.events.base_on_voice_state_update_event import BaseOnVoiceStateUpdateEvent
|
||||
from modules.boot_log.boot_log_on_ready_event import BootLogOnReadyEvent
|
||||
from modules.database.database_on_ready_event import DatabaseOnReadyEvent
|
||||
from modules.permission.events.permission_on_member_update_event import PermissionOnMemberUpdateEvent
|
||||
from modules.permission.events.permission_on_ready_event import PermissionOnReadyEvent
|
||||
|
||||
|
||||
class StartupDiscordExtension(StartupExtensionABC):
|
||||
@@ -35,34 +15,4 @@ class StartupDiscordExtension(StartupExtensionABC):
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_discord()
|
||||
dc = get_discord_collection(services)
|
||||
""" commands """
|
||||
# admin
|
||||
dc.add_command(RestartCommand)
|
||||
dc.add_command(ShutdownCommand)
|
||||
dc.add_command(DeployCommand)
|
||||
# moderator
|
||||
dc.add_command(PurgeCommand)
|
||||
# simple
|
||||
dc.add_command(AFKCommand)
|
||||
dc.add_command(HelpCommand)
|
||||
dc.add_command(InfoCommand)
|
||||
dc.add_command(PingCommand)
|
||||
dc.add_command(UserInfoCommand)
|
||||
""" events """
|
||||
# on_command_error
|
||||
dc.add_event(DiscordEventTypesEnum.on_command_error.value, BaseOnCommandErrorEvent)
|
||||
# on_member_join
|
||||
dc.add_event(DiscordEventTypesEnum.on_member_join.value, BaseOnMemberJoinEvent)
|
||||
# on_member_remove
|
||||
dc.add_event(DiscordEventTypesEnum.on_member_join.value, BaseOnMemberRemoveEvent)
|
||||
# on_member_update
|
||||
dc.add_event(DiscordEventTypesEnum.on_member_update.value, PermissionOnMemberUpdateEvent)
|
||||
# on_message
|
||||
dc.add_event(DiscordEventTypesEnum.on_message.value, BaseOnMessageEvent)
|
||||
# on_voice_state_update
|
||||
dc.add_event(DiscordEventTypesEnum.on_voice_state_update.value, BaseOnVoiceStateUpdateEvent)
|
||||
# on_ready
|
||||
dc.add_event(DiscordEventTypesEnum.on_ready.value, DatabaseOnReadyEvent)
|
||||
dc.add_event(DiscordEventTypesEnum.on_ready.value, PermissionOnReadyEvent)
|
||||
dc.add_event(DiscordEventTypesEnum.on_ready.value, BootLogOnReadyEvent) # has to be last
|
||||
dcc = get_discord_collection(services)
|
||||
|
@@ -4,6 +4,7 @@ from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
|
||||
from bot_data.abc.migration_abc import MigrationABC
|
||||
from bot_data.migration.auto_role_migration import AutoRoleMigration
|
||||
from bot_data.migration.initial_migration import InitialMigration
|
||||
from bot_data.service.migration_service import MigrationService
|
||||
|
||||
@@ -19,3 +20,4 @@ class StartupMigrationExtension(StartupExtensionABC):
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_transient(MigrationService)
|
||||
services.add_transient(MigrationABC, InitialMigration)
|
||||
services.add_transient(MigrationABC, AutoRoleMigration) # 03.10.2022 #54 - 0.2.2
|
||||
|
39
src/bot/startup_module_extension.py
Normal file
39
src/bot/startup_module_extension.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.application import StartupExtensionABC
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.console import Console, ForegroundColorEnum
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot.module_list import ModuleList
|
||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
||||
|
||||
|
||||
class StartupModuleExtension(StartupExtensionABC):
|
||||
|
||||
def __init__(self):
|
||||
self._config: Optional[ConfigurationABC] = None
|
||||
self._feature_flags: Optional[FeatureFlagsSettings] = None
|
||||
|
||||
self._modules = ModuleList.get_modules()
|
||||
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
self._config = config
|
||||
self._feature_flags = config.get_configuration(FeatureFlagsSettings)
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
provider = services.build_service_provider()
|
||||
dc_collection: DiscordCollectionABC = provider.get_service(DiscordCollectionABC)
|
||||
|
||||
for module_type in self._modules:
|
||||
module = module_type(dc_collection)
|
||||
if not self._feature_flags.get_flag(module.feature_flag):
|
||||
continue
|
||||
|
||||
Console.set_foreground_color(ForegroundColorEnum.green)
|
||||
Console.write_line(f'[{__name__}] Loaded module: {module_type}')
|
||||
Console.color_reset()
|
||||
module.configure_configuration(self._config, env)
|
||||
module.configure_services(services, env)
|
51
src/bot/startup_settings_extension.py
Normal file
51
src/bot/startup_settings_extension.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Callable, Type, Optional
|
||||
|
||||
from cpl_core.application import StartupExtensionABC
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
|
||||
from bot_core.configuration.bot_logging_settings import BotLoggingSettings
|
||||
from bot_core.configuration.bot_settings import BotSettings
|
||||
from modules.base.configuration.base_settings import BaseSettings
|
||||
from modules.boot_log.configuration.boot_log_settings import BootLogSettings
|
||||
from modules.permission.configuration.permission_settings import PermissionSettings
|
||||
|
||||
|
||||
class StartupSettingsExtension(StartupExtensionABC):
|
||||
|
||||
def __init__(self):
|
||||
self._start_time = datetime.now()
|
||||
|
||||
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC):
|
||||
# this shit has to be done here because we need settings in subsequent startup extensions
|
||||
environment.set_working_directory(os.path.dirname(os.path.realpath(__file__)))
|
||||
configuration.add_environment_variables('KDB_')
|
||||
configuration.add_environment_variables('DISCORD_')
|
||||
|
||||
configuration.add_json_file(f'config/appsettings.json', optional=False)
|
||||
configuration.add_json_file(f'config/appsettings.{environment.environment_name}.json', optional=True)
|
||||
configuration.add_json_file(f'config/appsettings.{environment.host_name}.json', optional=True)
|
||||
# load feature-flags
|
||||
configuration.add_json_file(f'config/feature-flags.json', optional=False)
|
||||
|
||||
configuration.add_configuration('Startup_StartTime', str(self._start_time))
|
||||
self._configure_settings_with_sub_settings(configuration, BotSettings, lambda x: x.servers, lambda x: x.id)
|
||||
self._configure_settings_with_sub_settings(configuration, BaseSettings, lambda x: x.servers, lambda x: x.id)
|
||||
self._configure_settings_with_sub_settings(configuration, BootLogSettings, lambda x: x.servers, lambda x: x.id)
|
||||
self._configure_settings_with_sub_settings(configuration, PermissionSettings, lambda x: x.servers, lambda x: x.id)
|
||||
self._configure_settings_with_sub_settings(configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key)
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _configure_settings_with_sub_settings(config: ConfigurationABC, settings: Type, list_atr: Callable, atr: Callable):
|
||||
settings: Optional[settings] = config.get_configuration(settings)
|
||||
if settings is None:
|
||||
return
|
||||
|
||||
for sub_settings in list_atr(settings):
|
||||
config.add_configuration(f'{type(sub_settings).__name__}_{atr(sub_settings)}', sub_settings)
|
@@ -4,6 +4,12 @@
|
||||
"bot_has_no_permission_message": "Ey!!!\nWas soll das?\nIch habe keine Berechtigungen :(\nScheiß System...",
|
||||
"no_permission_message": "Nein!\nIch höre nicht auf dich ¯\\_(ツ)_/¯",
|
||||
"not_implemented_yet": "Ey Alter, das kann ich noch nicht...",
|
||||
"presence": {
|
||||
"booting": "{} Ich fahre gerade hoch...",
|
||||
"running": "{} Behalte Ruhe und iss Kekse :D",
|
||||
"restart": "{} Muss neue Kekse holen...",
|
||||
"shutdown": "{} Ich werde bestimmt wieder kommen..."
|
||||
},
|
||||
"errors": {
|
||||
"error": "Es gab einen Fehler. Meld dich bitte bei einem Admin.",
|
||||
"command_error": "Es gab einen Fehler beim bearbeiten des Befehls. Meld dich bitte bei einem Admin.",
|
||||
@@ -37,7 +43,8 @@
|
||||
"extension_already_loaded": "Fehler: Erweiterung wurde bereits geladen!",
|
||||
"extension_not_loaded": "Fehler: Erweiterung wurde nicht geladen!",
|
||||
"no_entry_point_error": "Fehler: Kein Eintrittspunkt!",
|
||||
"extension_failed": "Fehler: Erweiterung ist fehlgeschlagen!"
|
||||
"extension_failed": "Fehler: Erweiterung ist fehlgeschlagen!",
|
||||
"bot_not_ready_yet": "Ey Alter! Gedulde dich doch mal! ..."
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
@@ -46,6 +53,57 @@
|
||||
"shutdown_message": "Trauert nicht um mich, es war eine logische Entscheidung. Das Wohl von Vielen, es wiegt schwerer als das Wohl von Wenigen oder eines Einzelnen. Ich war es und ich werde es immer sein, Euer Freund. Lebt lange und in Frieden :)",
|
||||
"deploy_message": "Der neue Stand wurde hochgeladen."
|
||||
},
|
||||
"auto_role": {
|
||||
"list": {
|
||||
"title": "Beobachtete Nachrichten:",
|
||||
"description": "Von auto-role beobachtete Nachrichten:",
|
||||
"auto_role_id": "auto-role Id",
|
||||
"message_id": "Nachricht-Id"
|
||||
},
|
||||
"add": {
|
||||
"success": "auto-role für die Nachricht {} wurde hinzugefügt :D",
|
||||
"error": {
|
||||
"not_found": "Nachricht {} in {} nicht gefunden!",
|
||||
"already_exists": "auto-role für die Nachricht {} existiert bereits!"
|
||||
}
|
||||
},
|
||||
"remove": {
|
||||
"success": "auto-role {} wurde entfernt :D",
|
||||
"error": {
|
||||
"not_found": "auto-role {} nicht gefunden!"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"nothing_found": "Keine auto-role Einträge gefunden."
|
||||
},
|
||||
"rule": {
|
||||
"list": {
|
||||
"title": "auto-role Regeln:",
|
||||
"description": "Von auto-role angewendete Regeln:",
|
||||
"auto_role_rule_id": "auto-role Regel Id",
|
||||
"emoji": "Emoji",
|
||||
"role": "Rolle"
|
||||
},
|
||||
"add": {
|
||||
"success": "Regel {} -> {} für auto-role {} wurde hinzugefügt :D",
|
||||
"error": {
|
||||
"not_found": "Regel für auto-role {} nicht gefunden!",
|
||||
"emoji_not_found": "Emoji {} für auto-role Regel {} nicht gefunden!",
|
||||
"rule_not_found": "Rolle {} für auto-role Regel {} nicht gefunden!",
|
||||
"already_exists": "Regel für auto-role {} existiert bereits!"
|
||||
}
|
||||
},
|
||||
"remove": {
|
||||
"success": "Regel für auto-role {} wurde entfernt :D",
|
||||
"error": {
|
||||
"not_found": "Regel für auto-role {} nicht gefunden!"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"id_not_found": "Kein auto-role Eintrag mit der Id gefunden!"
|
||||
}
|
||||
}
|
||||
},
|
||||
"moderator": {
|
||||
"purge_message": "Na gut..., ich lösche alle Nachrichten wenns sein muss."
|
||||
},
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_core'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_core.abc'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -1,5 +1,7 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from discord.ext.commands import Context
|
||||
|
||||
|
||||
class ClientUtilsServiceABC(ABC):
|
||||
|
||||
@@ -14,3 +16,9 @@ class ClientUtilsServiceABC(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def get_client(self, dc_ic: int, guild_id: int): pass
|
||||
|
||||
@abstractmethod
|
||||
async def check_if_bot_is_ready_yet_and_respond(self, ctx: Context) -> bool: pass
|
||||
|
||||
@abstractmethod
|
||||
async def presence_game(self, t_key: str): pass
|
||||
|
60
src/bot_core/abc/custom_file_logger_abc.py
Normal file
60
src/bot_core/abc/custom_file_logger_abc.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_core.logging import LoggingSettings, Logger, LoggingLevelEnum, LoggerABC
|
||||
from cpl_core.time import TimeFormatSettings
|
||||
|
||||
from bot_core.configuration.file_logging_settings import FileLoggingSettings
|
||||
|
||||
|
||||
class CustomFileLoggerABC(Logger, ABC):
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, key: str, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC):
|
||||
self._key = key
|
||||
settings: LoggingSettings = config.get_configuration(f'{FileLoggingSettings.__name__}_{key}')
|
||||
Logger.__init__(self, settings, time_format, env)
|
||||
self._begin_log()
|
||||
|
||||
def _begin_log(self):
|
||||
console_level = self._console.value
|
||||
self._console = LoggingLevelEnum.OFF
|
||||
self.info(__name__, f'Starting...')
|
||||
self._console = LoggingLevelEnum(console_level)
|
||||
|
||||
def _get_string(self, name_list_as_str: str, level: LoggingLevelEnum, message: str) -> str:
|
||||
names = name_list_as_str.split(' ')
|
||||
log_level = level.name
|
||||
string = f'<{self._get_datetime_now()}> [ {log_level} ]'
|
||||
for name in names:
|
||||
string += f' [ {name} ]'
|
||||
string += f': {message}'
|
||||
return string
|
||||
|
||||
def header(self, string: str):
|
||||
super().header(string)
|
||||
|
||||
def trace(self, name: str, message: str):
|
||||
name = f'{name} {self._key}'
|
||||
super().trace(name, message)
|
||||
|
||||
def debug(self, name: str, message: str):
|
||||
name = f'{name} {self._key}'
|
||||
super().debug(name, message)
|
||||
|
||||
def info(self, name: str, message: str):
|
||||
name = f'{name} {self._key}'
|
||||
super().info(name, message)
|
||||
|
||||
def warn(self, name: str, message: str):
|
||||
name = f'{name} {self._key}'
|
||||
super().warn(name, message)
|
||||
|
||||
def error(self, name: str, message: str, ex: Exception = None):
|
||||
name = f'{name} {self._key}'
|
||||
super().error(name, message, ex)
|
||||
|
||||
def fatal(self, name: str, message: str, ex: Exception = None):
|
||||
name = f'{name} {self._key}'
|
||||
super().fatal(name, message, ex)
|
20
src/bot_core/abc/module_abc.py
Normal file
20
src/bot_core/abc/module_abc.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from abc import abstractmethod
|
||||
|
||||
from cpl_core.application import StartupExtensionABC
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
|
||||
|
||||
class ModuleABC(StartupExtensionABC):
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, dc: DiscordCollectionABC, feature_flag: FeatureFlagsEnum):
|
||||
StartupExtensionABC.__init__(self)
|
||||
|
||||
self._dc = dc
|
||||
self._feature_flag = feature_flag
|
||||
|
||||
@property
|
||||
def feature_flag(self) -> FeatureFlagsEnum:
|
||||
return self._feature_flag
|
@@ -4,7 +4,7 @@
|
||||
"Version": {
|
||||
"Major": "1",
|
||||
"Minor": "0",
|
||||
"Micro": "0.dev1"
|
||||
"Micro": "0"
|
||||
},
|
||||
"Author": "Sven Heidemann",
|
||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||
@@ -16,10 +16,10 @@
|
||||
"LicenseName": "MIT",
|
||||
"LicenseDescription": "MIT, see LICENSE for more details.",
|
||||
"Dependencies": [
|
||||
"cpl-core>=2022.7.0"
|
||||
"cpl-core>=2022.10.0"
|
||||
],
|
||||
"DevDependencies": [
|
||||
"cpl-cli>=2022.7.0"
|
||||
"cpl-cli>=2022.10.0"
|
||||
],
|
||||
"PythonVersion": ">=3.10.4",
|
||||
"PythonPath": {
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_core.configuration'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
33
src/bot_core/configuration/bot_logging_settings.py
Normal file
33
src/bot_core/configuration/bot_logging_settings.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import traceback
|
||||
|
||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
||||
from cpl_core.console import Console, ForegroundColorEnum
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.configuration.file_logging_settings import FileLoggingSettings
|
||||
|
||||
|
||||
class BotLoggingSettings(ConfigurationModelABC):
|
||||
|
||||
def __init__(self):
|
||||
ConfigurationModelABC.__init__(self)
|
||||
self._files: List[FileLoggingSettings] = List(FileLoggingSettings)
|
||||
|
||||
@property
|
||||
def files(self) -> List[FileLoggingSettings]:
|
||||
return self._files
|
||||
|
||||
def from_dict(self, settings: dict):
|
||||
try:
|
||||
files = List(FileLoggingSettings)
|
||||
for s in settings:
|
||||
st = FileLoggingSettings()
|
||||
settings[s]['Key'] = s
|
||||
st.from_dict(settings[s])
|
||||
files.append(st)
|
||||
self._files = files
|
||||
except Exception as e:
|
||||
Console.set_foreground_color(ForegroundColorEnum.red)
|
||||
Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings')
|
||||
Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')
|
||||
Console.set_foreground_color(ForegroundColorEnum.default)
|
@@ -12,28 +12,35 @@ class BotSettings(ConfigurationModelABC):
|
||||
def __init__(self):
|
||||
ConfigurationModelABC.__init__(self)
|
||||
|
||||
self._servers: List[ServerSettings] = List()
|
||||
self._technicians: list[int] = []
|
||||
self._deploy_file_path = './'
|
||||
self._servers: List[ServerSettings] = List(ServerSettings)
|
||||
self._technicians: List[int] = List(int)
|
||||
self._wait_for_restart = 2
|
||||
self._wait_for_shutdown = 2
|
||||
|
||||
@property
|
||||
def servers(self) -> List[ServerSettings]:
|
||||
return self._servers
|
||||
|
||||
@property
|
||||
def technicians(self) -> list[int]:
|
||||
def technicians(self) -> List[int]:
|
||||
return self._technicians
|
||||
|
||||
@property
|
||||
def deploy_file_path(self) -> str:
|
||||
return self._deploy_file_path
|
||||
def wait_for_restart(self) -> int:
|
||||
return self._wait_for_restart
|
||||
|
||||
@property
|
||||
def wait_for_shutdown(self) -> int:
|
||||
return self._wait_for_shutdown
|
||||
|
||||
def from_dict(self, settings: dict):
|
||||
try:
|
||||
self._technicians = settings["Technicians"]
|
||||
self._deploy_file_path = settings["DeployFilesPath"]
|
||||
self._wait_for_restart = settings["WaitForRestart"]
|
||||
self._wait_for_shutdown = settings["WaitForShutdown"]
|
||||
settings.pop("Technicians")
|
||||
settings.pop("DeployFilesPath")
|
||||
settings.pop("WaitForRestart")
|
||||
settings.pop("WaitForShutdown")
|
||||
servers = List(ServerSettings)
|
||||
for s in settings:
|
||||
st = ServerSettings()
|
||||
|
18
src/bot_core/configuration/feature_flags_enum.py
Normal file
18
src/bot_core/configuration/feature_flags_enum.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class FeatureFlagsEnum(Enum):
|
||||
|
||||
# modules
|
||||
admin_module = 'AdminModule'
|
||||
auto_role_module = 'AutoRoleModule'
|
||||
base_module = 'BaseModule'
|
||||
boot_log_module = 'BootLogModule'
|
||||
core_module = 'CoreModule'
|
||||
core_extension_module = 'CoreExtensionModule'
|
||||
data_module = 'DataModule',
|
||||
database_module = 'DatabaseModule',
|
||||
moderator_module = 'ModeratorModule'
|
||||
permission_module = 'PermissionModule'
|
||||
# features
|
||||
presence = 'Presence'
|
48
src/bot_core/configuration/feature_flags_settings.py
Normal file
48
src/bot_core/configuration/feature_flags_settings.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import traceback
|
||||
from typing import Optional, Callable
|
||||
|
||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
||||
from cpl_core.console import Console
|
||||
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
|
||||
|
||||
class FeatureFlagsSettings(ConfigurationModelABC):
|
||||
|
||||
def __init__(self):
|
||||
ConfigurationModelABC.__init__(self)
|
||||
|
||||
self._flags = {
|
||||
# modules
|
||||
FeatureFlagsEnum.admin_module.value: False, # 02.10.2022 #48
|
||||
FeatureFlagsEnum.auto_role_module.value: True, # 03.10.2022 #54
|
||||
FeatureFlagsEnum.base_module.value: True, # 02.10.2022 #48
|
||||
FeatureFlagsEnum.boot_log_module.value: True, # 02.10.2022 #48
|
||||
FeatureFlagsEnum.core_module.value: True, # 03.10.2022 #56
|
||||
FeatureFlagsEnum.core_extension_module.value: True, # 03.10.2022 #56
|
||||
FeatureFlagsEnum.data_module.value: True, # 03.10.2022 #56
|
||||
FeatureFlagsEnum.database_module.value: True, # 02.10.2022 #48
|
||||
FeatureFlagsEnum.moderator_module.value: False, # 02.10.2022 #48
|
||||
FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48
|
||||
# features
|
||||
FeatureFlagsEnum.presence.value: True, # 03.10.2022 #56
|
||||
}
|
||||
|
||||
def get_flag(self, key: FeatureFlagsEnum) -> bool:
|
||||
if key.value not in self._flags:
|
||||
return False
|
||||
return self._flags[key.value]
|
||||
|
||||
def _load_flag(self, settings: dict, key: FeatureFlagsEnum):
|
||||
if key.value not in settings:
|
||||
return
|
||||
|
||||
self._flags[key.value] = bool(settings[key.value])
|
||||
|
||||
def from_dict(self, settings: dict):
|
||||
try:
|
||||
for flag in [f.value for f in FeatureFlagsEnum]:
|
||||
self._load_flag(settings, FeatureFlagsEnum(flag))
|
||||
except Exception as e:
|
||||
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings')
|
||||
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')
|
24
src/bot_core/configuration/file_logging_settings.py
Normal file
24
src/bot_core/configuration/file_logging_settings.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import traceback
|
||||
|
||||
from cpl_core.console import Console
|
||||
from cpl_core.logging import LoggingSettings
|
||||
|
||||
|
||||
class FileLoggingSettings(LoggingSettings):
|
||||
|
||||
def __init__(self):
|
||||
LoggingSettings.__init__(self)
|
||||
|
||||
self._key = ''
|
||||
|
||||
@property
|
||||
def key(self) -> str:
|
||||
return self._key
|
||||
|
||||
def from_dict(self, settings: dict):
|
||||
try:
|
||||
self._key = settings['Key']
|
||||
super().from_dict(settings)
|
||||
except Exception as e:
|
||||
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings')
|
||||
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')
|
26
src/bot_core/core_extension/__init__.py
Normal file
26
src/bot_core/core_extension/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'bot_core.core_extension'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
21
src/bot_core/core_extension/core_extension_module.py
Normal file
21
src/bot_core/core_extension/core_extension_module.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from bot_core.core_extension.core_extension_on_ready_event import CoreExtensionOnReadyEvent
|
||||
|
||||
|
||||
class CoreExtensionModule(ModuleABC):
|
||||
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_extension_module)
|
||||
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent)
|
32
src/bot_core/core_extension/core_extension_on_ready_event.py
Normal file
32
src/bot_core/core_extension/core_extension_on_ready_event.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import asyncio
|
||||
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.events import OnReadyABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
|
||||
|
||||
class CoreExtensionOnReadyEvent(OnReadyABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
t: TranslatePipe
|
||||
):
|
||||
OnReadyABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
self._client_utils = client_utils
|
||||
self._t = t
|
||||
|
||||
self._logger.info(__name__, f'Module {type(self)} loaded')
|
||||
|
||||
async def on_ready(self):
|
||||
self._logger.debug(__name__, f'Module {type(self)} started')
|
||||
await self._client_utils.presence_game('common.presence.running')
|
||||
self._logger.trace(__name__, f'Module {type(self)} stopped')
|
32
src/bot_core/core_module.py
Normal file
32
src/bot_core/core_module.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from bot_core.events.core_on_ready_event import CoreOnReadyEvent
|
||||
from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe
|
||||
from bot_core.service.client_utils_service import ClientUtilsService
|
||||
from bot_core.service.message_service import MessageService
|
||||
|
||||
|
||||
class CoreModule(ModuleABC):
|
||||
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_module)
|
||||
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_transient(MessageServiceABC, MessageService)
|
||||
services.add_transient(ClientUtilsServiceABC, ClientUtilsService)
|
||||
|
||||
# pipes
|
||||
services.add_transient(DateTimeOffsetPipe)
|
||||
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_ready.value, CoreOnReadyEvent)
|
26
src/bot_core/events/__init__.py
Normal file
26
src/bot_core/events/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'bot_core.events'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
30
src/bot_core/events/core_on_ready_event.py
Normal file
30
src/bot_core/events/core_on_ready_event.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.events import OnReadyABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
|
||||
|
||||
class CoreOnReadyEvent(OnReadyABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
t: TranslatePipe,
|
||||
):
|
||||
OnReadyABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
self._client_utils = client_utils
|
||||
self._t = t
|
||||
|
||||
self._logger.info(__name__, f'Module {type(self)} loaded')
|
||||
|
||||
async def on_ready(self):
|
||||
self._logger.debug(__name__, f'Module {type(self)} started')
|
||||
await self._client_utils.presence_game('common.presence.booting')
|
||||
self._logger.trace(__name__, f'Module {type(self)} stopped')
|
26
src/bot_core/helper/__init__.py
Normal file
26
src/bot_core/helper/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'bot_core.helper'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
9
src/bot_core/helper/log_message_helper.py
Normal file
9
src/bot_core/helper/log_message_helper.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import discord
|
||||
|
||||
|
||||
class LogMessageHelper:
|
||||
|
||||
@staticmethod
|
||||
def get_log_string(message: discord.Message):
|
||||
content = message.content.replace("\n", "\n\t")
|
||||
return f'{message.author} @ {message.channel} -> \n\t{content}'
|
26
src/bot_core/logging/__init__.py
Normal file
26
src/bot_core/logging/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'bot_core.logging'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
11
src/bot_core/logging/command_logger.py
Normal file
11
src/bot_core/logging/command_logger.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_core.time import TimeFormatSettings
|
||||
|
||||
from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC
|
||||
|
||||
|
||||
class CommandLogger(CustomFileLoggerABC):
|
||||
|
||||
def __init__(self, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC):
|
||||
CustomFileLoggerABC.__init__(self, 'Command', config, time_format, env)
|
11
src/bot_core/logging/database_logger.py
Normal file
11
src/bot_core/logging/database_logger.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_core.time import TimeFormatSettings
|
||||
|
||||
from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC
|
||||
|
||||
|
||||
class DatabaseLogger(CustomFileLoggerABC):
|
||||
|
||||
def __init__(self, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC):
|
||||
CustomFileLoggerABC.__init__(self, 'Database', config, time_format, env)
|
11
src/bot_core/logging/message_logger.py
Normal file
11
src/bot_core/logging/message_logger.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_core.time import TimeFormatSettings
|
||||
|
||||
from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC
|
||||
|
||||
|
||||
class MessageLogger(CustomFileLoggerABC):
|
||||
|
||||
def __init__(self, config: ConfigurationABC, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC):
|
||||
CustomFileLoggerABC.__init__(self, 'Message', config, time_format, env)
|
@@ -15,7 +15,7 @@ __title__ = 'bot_core.pipes'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_core.service'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -1,8 +1,16 @@
|
||||
import discord
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
|
||||
@@ -11,16 +19,26 @@ class ClientUtilsService(ClientUtilsServiceABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: ConfigurationABC,
|
||||
logger: LoggerABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
servers: ServerRepositoryABC,
|
||||
clients: ClientRepositoryABC,
|
||||
db: DatabaseContextABC
|
||||
message_service: MessageServiceABC,
|
||||
db: DatabaseContextABC,
|
||||
t: TranslatePipe,
|
||||
feature_flags: FeatureFlagsSettings
|
||||
):
|
||||
ClientUtilsServiceABC.__init__(self)
|
||||
self._config = config
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
self._servers = servers
|
||||
self._clients = clients
|
||||
self._message_service = message_service
|
||||
self._db = db
|
||||
self._t = t
|
||||
self._feature_flags = feature_flags
|
||||
|
||||
def received_command(self, guild_id: int):
|
||||
server = self._servers.get_server_by_discord_id(guild_id)
|
||||
@@ -40,3 +58,20 @@ class ClientUtilsService(ClientUtilsServiceABC):
|
||||
server = self._servers.get_server_by_discord_id(guild_id)
|
||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.server_id)
|
||||
return client
|
||||
|
||||
async def check_if_bot_is_ready_yet_and_respond(self, ctx: Context) -> bool:
|
||||
if self._config.get_configuration('IS_READY') == 'true':
|
||||
return True
|
||||
|
||||
self._logger.debug(__name__, f'Bot is not ready yet {self._t.transform("common.errors.bot_not_ready_yet")}')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.errors.bot_not_ready_yet'), without_tracking=True)
|
||||
return False
|
||||
|
||||
async def presence_game(self, t_key: str):
|
||||
if not self._feature_flags.get_flag(FeatureFlagsEnum.presence):
|
||||
return
|
||||
|
||||
import bot
|
||||
name = self._t.transform(t_key).format(bot.__version__)
|
||||
await self._bot.change_presence(activity=discord.Game(name=name))
|
||||
self._logger.info(__name__, f'Set presence {name}')
|
||||
|
@@ -4,19 +4,20 @@ from typing import Union
|
||||
import discord
|
||||
from cpl_core.configuration.configuration_abc import ConfigurationABC
|
||||
from cpl_core.database.context.database_context_abc import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_query.extension import List
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.configuration.server_settings import ServerSettings
|
||||
from bot_core.helper.log_message_helper import LogMessageHelper
|
||||
from bot_core.logging.message_logger import MessageLogger
|
||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||
|
||||
|
||||
class MessageService(MessageServiceABC):
|
||||
|
||||
def __init__(self, config: ConfigurationABC, logger: LoggerABC, bot: DiscordBotServiceABC, clients: ClientRepositoryABC, db: DatabaseContextABC):
|
||||
def __init__(self, config: ConfigurationABC, logger: MessageLogger, bot: DiscordBotServiceABC, clients: ClientRepositoryABC, db: DatabaseContextABC):
|
||||
self._config = config
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
@@ -35,10 +36,11 @@ class MessageService(MessageServiceABC):
|
||||
server_st: ServerSettings = self._config.get_configuration(f'ServerSettings_{message.guild.id}')
|
||||
if not mass_delete:
|
||||
await asyncio.sleep(server_st.message_delete_timer)
|
||||
self._logger.debug(__name__, f'Try to delete message:\n\t{message}\n\t{message.content}')
|
||||
self._logger.debug(__name__, f'Try to delete message: {LogMessageHelper.get_log_string(message)}')
|
||||
guild_id = message.guild.id
|
||||
try:
|
||||
await message.delete()
|
||||
await asyncio.sleep(server_st.message_delete_timer)
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, f'Deleting message failed', e)
|
||||
else:
|
||||
@@ -104,8 +106,7 @@ class MessageService(MessageServiceABC):
|
||||
await asyncio.sleep(wait_before_delete)
|
||||
|
||||
if is_persistent:
|
||||
await self.delete_message(ctx.message, without_tracking)
|
||||
return
|
||||
|
||||
if ctx.guild is not None:
|
||||
await self.delete_messages(List(discord.Message, [msg, ctx.message]), ctx.guild.id)
|
||||
await self.delete_message(msg, without_tracking)
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_data'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_data.abc'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
58
src/bot_data/abc/auto_role_repository_abc.py
Normal file
58
src/bot_data/abc/auto_role_repository_abc.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Optional
|
||||
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_data.model.auto_role import AutoRole
|
||||
from bot_data.model.auto_role_rule import AutoRoleRule
|
||||
|
||||
|
||||
class AutoRoleRepositoryABC(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self): pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_roles(self) -> List[AutoRole]: pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_role_by_id(self, id: int) -> AutoRole: pass
|
||||
|
||||
@abstractmethod
|
||||
def find_auto_role_by_id(self, id: int) -> Optional[AutoRole]: pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_roles_by_server_id(self, id: int) -> AutoRole: pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_role_by_message_id(self, id: int) -> AutoRole: pass
|
||||
|
||||
@abstractmethod
|
||||
def find_auto_role_by_message_id(self, id: int) -> Optional[AutoRole]: pass
|
||||
|
||||
@abstractmethod
|
||||
def add_auto_role(self, auto_role: AutoRole): pass
|
||||
|
||||
@abstractmethod
|
||||
def update_auto_role(self, auto_role: AutoRole): pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_auto_role(self, auto_role: AutoRole): pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_role_rules(self) -> List[AutoRoleRule]: pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_role_rule_by_id(self, id: int) -> AutoRoleRule: pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_role_rules_by_auto_role_id(self, id: int) -> List[AutoRoleRule]: pass
|
||||
|
||||
@abstractmethod
|
||||
def add_auto_role_rule(self, auto_role: AutoRoleRule): pass
|
||||
|
||||
@abstractmethod
|
||||
def update_auto_role_rule(self, auto_role: AutoRoleRule): pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_auto_role_rule(self, auto_role: AutoRoleRule): pass
|
@@ -2,6 +2,7 @@ from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class MigrationABC(ABC):
|
||||
name = None
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self): pass
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"Version": {
|
||||
"Major": "1",
|
||||
"Minor": "0",
|
||||
"Micro": "0.dev1"
|
||||
"Micro": "0"
|
||||
},
|
||||
"Author": "Sven Heidemann",
|
||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||
@@ -16,10 +16,10 @@
|
||||
"LicenseName": "MIT",
|
||||
"LicenseDescription": "MIT, see LICENSE for more details.",
|
||||
"Dependencies": [
|
||||
"cpl-core>=2022.7.0"
|
||||
"cpl-core>=2022.10.0"
|
||||
],
|
||||
"DevDependencies": [
|
||||
"cpl-cli>=2022.7.0.post1"
|
||||
"cpl-cli>=2022.10.0"
|
||||
],
|
||||
"PythonVersion": ">=3.10.4",
|
||||
"PythonPath": {
|
||||
|
39
src/bot_data/data_module.py
Normal file
39
src/bot_data/data_module.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
||||
from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
|
||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService
|
||||
from bot_data.service.client_repository_service import ClientRepositoryService
|
||||
from bot_data.service.known_user_repository_service import KnownUserRepositoryService
|
||||
from bot_data.service.server_repository_service import ServerRepositoryService
|
||||
from bot_data.service.user_joined_server_repository_service import UserJoinedServerRepositoryService
|
||||
from bot_data.service.user_joined_voice_channel_service import UserJoinedVoiceChannelRepositoryService
|
||||
from bot_data.service.user_repository_service import UserRepositoryService
|
||||
|
||||
|
||||
class DataModule(ModuleABC):
|
||||
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.data_module)
|
||||
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_transient(ServerRepositoryABC, ServerRepositoryService)
|
||||
services.add_transient(UserRepositoryABC, UserRepositoryService)
|
||||
services.add_transient(ClientRepositoryABC, ClientRepositoryService)
|
||||
services.add_transient(KnownUserRepositoryABC, KnownUserRepositoryService)
|
||||
services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService)
|
||||
services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService)
|
||||
services.add_transient(AutoRoleRepositoryABC, AutoRoleRepositoryService)
|
@@ -1,11 +1,12 @@
|
||||
from cpl_core.database import DatabaseSettings
|
||||
from cpl_core.database.context import DatabaseContext
|
||||
from cpl_core.logging import LoggerABC
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
|
||||
|
||||
class DBContext(DatabaseContext):
|
||||
|
||||
def __init__(self, logger: LoggerABC):
|
||||
def __init__(self, logger: DatabaseLogger):
|
||||
|
||||
self._logger = logger
|
||||
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_data.migration'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
47
src/bot_data/migration/auto_role_migration.py
Normal file
47
src/bot_data/migration/auto_role_migration.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.migration_abc import MigrationABC
|
||||
from bot_data.db_context import DBContext
|
||||
|
||||
|
||||
class AutoRoleMigration(MigrationABC):
|
||||
name = '0.2.1_AutoRoleMigration'
|
||||
|
||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
||||
MigrationABC.__init__(self)
|
||||
self._logger = logger
|
||||
self._db = db
|
||||
self._cursor = db.cursor
|
||||
|
||||
def upgrade(self):
|
||||
self._logger.debug(__name__, 'Running upgrade')
|
||||
|
||||
self._cursor.execute(
|
||||
str(f"""
|
||||
CREATE TABLE IF NOT EXISTS `AutoRoles` (
|
||||
`AutoRoleId` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`ServerId` BIGINT,
|
||||
`DiscordMessageId` BIGINT NOT NULL,
|
||||
`CreatedAt` DATETIME(6),
|
||||
`LastModifiedAt` DATETIME(6),
|
||||
PRIMARY KEY(`AutoRoleId`)
|
||||
);
|
||||
""")
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(f"""
|
||||
CREATE TABLE IF NOT EXISTS `AutoRoleRules` (
|
||||
`AutoRoleRuleId` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`AutoRoleId` BIGINT,
|
||||
`DiscordEmojiName` VARCHAR(64),
|
||||
`DiscordRoleId` BIGINT NOT NULL,
|
||||
`CreatedAt` DATETIME(6),
|
||||
`LastModifiedAt` DATETIME(6),
|
||||
PRIMARY KEY(`AutoRoleRuleId`)
|
||||
);
|
||||
""")
|
||||
)
|
||||
|
||||
def downgrade(self):
|
||||
self._cursor.execute('DROP TABLE `AutoRole`;')
|
||||
self._cursor.execute('DROP TABLE `AutoRoleRules`;')
|
@@ -1,12 +1,13 @@
|
||||
from cpl_core.logging import LoggerABC
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.migration_abc import MigrationABC
|
||||
from bot_data.db_context import DBContext
|
||||
|
||||
|
||||
class InitialMigration(MigrationABC):
|
||||
name = '0.1_InitialMigration'
|
||||
|
||||
def __init__(self, logger: LoggerABC, db: DBContext):
|
||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
||||
MigrationABC.__init__(self)
|
||||
self._logger = logger
|
||||
self._db = db
|
||||
self._cursor = db.cursor
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_data.model'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
85
src/bot_data/model/auto_role.py
Normal file
85
src/bot_data/model/auto_role.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database import TableABC
|
||||
|
||||
|
||||
class AutoRole(TableABC):
|
||||
|
||||
def __init__(self, server_id: int, dc_message_id: int, created_at: datetime=None, modified_at: datetime=None, id=0):
|
||||
self._auto_role_id = id
|
||||
self._server_id = server_id
|
||||
self._discord_message_id = dc_message_id
|
||||
|
||||
TableABC.__init__(self)
|
||||
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
|
||||
|
||||
@property
|
||||
def auto_role_id(self) -> int:
|
||||
return self._auto_role_id
|
||||
|
||||
@property
|
||||
def server_id(self) -> int:
|
||||
return self._server_id
|
||||
|
||||
@property
|
||||
def discord_message_id(self) -> int:
|
||||
return self._discord_message_id
|
||||
|
||||
@staticmethod
|
||||
def get_select_all_string() -> str:
|
||||
return str(f"""
|
||||
SELECT * FROM `AutoRoles`;
|
||||
""")
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_id_string(id: int) -> str:
|
||||
return str(f"""
|
||||
SELECT * FROM `AutoRoles`
|
||||
WHERE `AutoRoleId` = {id};
|
||||
""")
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_server_id_string(id: int) -> str:
|
||||
return str(f"""
|
||||
SELECT * FROM `AutoRoles`
|
||||
WHERE `ServerId` = {id};
|
||||
""")
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_message_id_string(id: int) -> str:
|
||||
return str(f"""
|
||||
SELECT * FROM `AutoRoles`
|
||||
WHERE `DiscordMessageId` = {id};
|
||||
""")
|
||||
|
||||
@property
|
||||
def insert_string(self) -> str:
|
||||
return str(f"""
|
||||
INSERT INTO `AutoRoles` (
|
||||
`ServerId`, `DiscordMessageId`, `CreatedAt`, `LastModifiedAt`
|
||||
) VALUES (
|
||||
{self._server_id},
|
||||
{self._discord_message_id},
|
||||
'{self._created_at}',
|
||||
'{self._modified_at}'
|
||||
);
|
||||
""")
|
||||
|
||||
@property
|
||||
def udpate_string(self) -> str:
|
||||
return str(f"""
|
||||
UPDATE `AutoRoles`
|
||||
SET `ServerId` = {self._server_id},
|
||||
`DiscordMessageId` = {self._discord_message_id},
|
||||
`LastModifiedAt` = '{self._modified_at}'
|
||||
WHERE `AutoRoleId` = {self._auto_role_id};
|
||||
""")
|
||||
|
||||
@property
|
||||
def delete_string(self) -> str:
|
||||
return str(f"""
|
||||
DELETE FROM `AutoRoles`
|
||||
WHERE `AutoRoleId` = {self._auto_role_id};
|
||||
""")
|
85
src/bot_data/model/auto_role_rule.py
Normal file
85
src/bot_data/model/auto_role_rule.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database import TableABC
|
||||
|
||||
|
||||
class AutoRoleRule(TableABC):
|
||||
|
||||
def __init__(self, auto_role_id: int, discord_emoji_name: str, discord_role_id: int, created_at: datetime=None, modified_at: datetime=None, id=0):
|
||||
self._auto_role_rule_id = id
|
||||
self._auto_role_id = auto_role_id
|
||||
self._discord_emoji_name = discord_emoji_name
|
||||
self._discord_role_id = discord_role_id
|
||||
|
||||
TableABC.__init__(self)
|
||||
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
|
||||
|
||||
@property
|
||||
def auto_role_rule_id(self) -> int:
|
||||
return self._auto_role_rule_id
|
||||
|
||||
@property
|
||||
def auto_role_id(self) -> int:
|
||||
return self._auto_role_id
|
||||
|
||||
@property
|
||||
def emoji_name(self) -> str:
|
||||
return self._discord_emoji_name
|
||||
|
||||
@property
|
||||
def role_id(self) -> int:
|
||||
return self._discord_role_id
|
||||
|
||||
@staticmethod
|
||||
def get_select_all_string() -> str:
|
||||
return str(f"""
|
||||
SELECT * FROM `AutoRoleRules`;
|
||||
""")
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_id_string(id: int) -> str:
|
||||
return str(f"""
|
||||
SELECT * FROM `AutoRoleRules`
|
||||
WHERE `AutoRoleRuleId` = {id};
|
||||
""")
|
||||
|
||||
@staticmethod
|
||||
def get_select_by_auto_role_id_string(id: int) -> str:
|
||||
return str(f"""
|
||||
SELECT * FROM `AutoRoleRules`
|
||||
WHERE `AutoRoleId` = {id};
|
||||
""")
|
||||
|
||||
@property
|
||||
def insert_string(self) -> str:
|
||||
return str(f"""
|
||||
INSERT INTO `AutoRoleRules` (
|
||||
`AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `CreatedAt`, `LastModifiedAt`
|
||||
) VALUES (
|
||||
{self._auto_role_id},
|
||||
'{self._discord_emoji_name}',
|
||||
{self._discord_role_id},
|
||||
'{self._created_at}',
|
||||
'{self._modified_at}'
|
||||
);
|
||||
""")
|
||||
|
||||
@property
|
||||
def udpate_string(self) -> str:
|
||||
return str(f"""
|
||||
UPDATE `AutoRoleRules`
|
||||
SET `AutoRoleId` = {self._auto_role_id},
|
||||
`DiscordEmojiName` = {self._discord_emoji_name},
|
||||
`DiscordRoleId` = {self._discord_role_id},
|
||||
`LastModifiedAt` = '{self._modified_at}'
|
||||
WHERE `AutoRoleRuleId` = {self._auto_role_rule_id};
|
||||
""")
|
||||
|
||||
@property
|
||||
def delete_string(self) -> str:
|
||||
return str(f"""
|
||||
DELETE FROM `AutoRoleRules`
|
||||
WHERE `AutoRoleRuleId` = {self._auto_role_rule_id};
|
||||
""")
|
@@ -60,12 +60,12 @@ class Server(TableABC):
|
||||
UPDATE `Servers`
|
||||
SET `DiscordServerId` = {self._discord_server_id},
|
||||
`LastModifiedAt` = '{self._modified_at}'
|
||||
WHERE `Id` = {self._server_id};
|
||||
WHERE `ServerId` = {self._server_id};
|
||||
""")
|
||||
|
||||
@property
|
||||
def delete_string(self) -> str:
|
||||
return str(f"""
|
||||
DELETE FROM `Servers`
|
||||
WHERE `Id` = {self._server_id};
|
||||
WHERE `ServerId` = {self._server_id};
|
||||
""")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'bot_data.service'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
170
src/bot_data/service/auto_role_repository_service.py
Normal file
170
src/bot_data/service/auto_role_repository_service.py
Normal file
@@ -0,0 +1,170 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||
from bot_data.model.auto_role import AutoRole
|
||||
from bot_data.model.auto_role_rule import AutoRoleRule
|
||||
|
||||
|
||||
class AutoRoleRepositoryService(AutoRoleRepositoryABC):
|
||||
|
||||
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
AutoRoleRepositoryABC.__init__(self)
|
||||
|
||||
def get_auto_roles(self) -> List[AutoRole]:
|
||||
auto_roles = List(AutoRole)
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_all_string()}')
|
||||
results = self._context.select(AutoRole.get_select_all_string())
|
||||
for result in results:
|
||||
auto_roles.append(AutoRole(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
id=result[0]
|
||||
))
|
||||
|
||||
return auto_roles
|
||||
|
||||
def get_auto_role_by_id(self, id: int) -> AutoRole:
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_id_string(id)}')
|
||||
result = self._context.select(AutoRole.get_select_by_id_string(id))[0]
|
||||
return AutoRole(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
id=result[0]
|
||||
)
|
||||
|
||||
def find_auto_role_by_id(self, id: int) -> Optional[AutoRole]:
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_id_string(id)}')
|
||||
result = self._context.select(AutoRole.get_select_by_id_string(id))
|
||||
if result is None or len(result) == 0:
|
||||
return None
|
||||
|
||||
result = result[0]
|
||||
|
||||
return AutoRole(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
id=result[0]
|
||||
)
|
||||
|
||||
def get_auto_roles_by_server_id(self, id: int) -> List[AutoRole]:
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_server_id_string(id)}')
|
||||
auto_roles = List(AutoRole)
|
||||
results = self._context.select(AutoRole.get_select_by_server_id_string(id))
|
||||
for result in results:
|
||||
auto_roles.append(AutoRole(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
id=result[0]
|
||||
))
|
||||
|
||||
return auto_roles
|
||||
|
||||
def get_auto_role_by_message_id(self, id: int) -> AutoRole:
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_message_id_string(id)}')
|
||||
result = self._context.select(AutoRole.get_select_by_message_id_string(id))[0]
|
||||
return AutoRole(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
id=result[0]
|
||||
)
|
||||
|
||||
def find_auto_role_by_message_id(self, id: int) -> Optional[AutoRole]:
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRole.get_select_by_message_id_string(id)}')
|
||||
result = self._context.select(AutoRole.get_select_by_message_id_string(id))
|
||||
if result is None or len(result) == 0:
|
||||
return None
|
||||
|
||||
result = result[0]
|
||||
|
||||
return AutoRole(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
id=result[0]
|
||||
)
|
||||
|
||||
def add_auto_role(self, auto_role: AutoRole):
|
||||
self._logger.trace(__name__, f'Send SQL command: {auto_role.insert_string}')
|
||||
self._context.cursor.execute(auto_role.insert_string)
|
||||
|
||||
def update_auto_role(self, auto_role: AutoRole):
|
||||
self._logger.trace(__name__, f'Send SQL command: {auto_role.udpate_string}')
|
||||
self._context.cursor.execute(auto_role.udpate_string)
|
||||
|
||||
def delete_auto_role(self, auto_role: AutoRole):
|
||||
self._logger.trace(__name__, f'Send SQL command: {auto_role.delete_string}')
|
||||
self._context.cursor.execute(auto_role.delete_string)
|
||||
|
||||
def get_auto_role_rules(self) -> List[AutoRoleRule]:
|
||||
auto_role_rules = List(AutoRoleRule)
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRoleRule.get_select_all_string()}')
|
||||
results = self._context.select(AutoRoleRule.get_select_all_string())
|
||||
for result in results:
|
||||
auto_role_rules.append(AutoRoleRule(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
result[5],
|
||||
id=result[0]
|
||||
))
|
||||
|
||||
return auto_role_rules
|
||||
|
||||
def get_auto_role_rule_by_id(self, id: int) -> AutoRoleRule:
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRoleRule.get_select_by_id_string(id)}')
|
||||
result = self._context.select(AutoRoleRule.get_select_by_id_string(id))[0]
|
||||
return AutoRoleRule(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
result[5],
|
||||
id=result[0]
|
||||
)
|
||||
|
||||
def get_auto_role_rules_by_auto_role_id(self, id: int) -> List[AutoRoleRule]:
|
||||
auto_role_rules = List(AutoRoleRule)
|
||||
self._logger.trace(__name__, f'Send SQL command: {AutoRoleRule.get_select_by_auto_role_id_string(id)}')
|
||||
results = self._context.select(AutoRoleRule.get_select_by_auto_role_id_string(id))
|
||||
for result in results:
|
||||
auto_role_rules.append(AutoRoleRule(
|
||||
result[1],
|
||||
result[2],
|
||||
result[3],
|
||||
result[4],
|
||||
result[5],
|
||||
id=result[0]
|
||||
))
|
||||
|
||||
return auto_role_rules
|
||||
|
||||
def add_auto_role_rule(self, auto_role_rule: AutoRoleRule):
|
||||
self._logger.trace(__name__, f'Send SQL command: {auto_role_rule.insert_string}')
|
||||
self._context.cursor.execute(auto_role_rule.insert_string)
|
||||
|
||||
def update_auto_role_rule(self, auto_role_rule: AutoRoleRule):
|
||||
self._logger.trace(__name__, f'Send SQL command: {auto_role_rule.udpate_string}')
|
||||
self._context.cursor.execute(auto_role_rule.udpate_string)
|
||||
|
||||
def delete_auto_role_rule(self, auto_role_rule: AutoRoleRule):
|
||||
self._logger.trace(__name__, f'Send SQL command: {auto_role_rule.delete_string}')
|
||||
self._context.cursor.execute(auto_role_rule.delete_string)
|
@@ -1,8 +1,9 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.model.client import Client
|
||||
@@ -10,7 +11,7 @@ from bot_data.model.client import Client
|
||||
|
||||
class ClientRepositoryService(ClientRepositoryABC):
|
||||
|
||||
def __init__(self, logger: LoggerABC, db_context: DatabaseContextABC, servers: ServerRepositoryABC):
|
||||
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
|
@@ -1,16 +1,17 @@
|
||||
from typing import Optional
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_query.extension import List
|
||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.model.known_user import KnownUser
|
||||
|
||||
|
||||
class KnownUserRepositoryService(KnownUserRepositoryABC):
|
||||
|
||||
def __init__(self, logger: LoggerABC, db_context: DatabaseContextABC, servers: ServerRepositoryABC):
|
||||
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
|
@@ -2,22 +2,23 @@ from typing import Type
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.dependency_injection import ServiceProviderABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.migration_abc import MigrationABC
|
||||
from bot_data.model.migration_history import MigrationHistory
|
||||
|
||||
|
||||
class MigrationService:
|
||||
|
||||
def __init__(self, logger: LoggerABC, services: ServiceProviderABC, db: DatabaseContextABC):
|
||||
def __init__(self, logger: DatabaseLogger, services: ServiceProviderABC, db: DatabaseContextABC):
|
||||
self._logger = logger
|
||||
self._services = services
|
||||
|
||||
self._db = db
|
||||
self._cursor = db.cursor
|
||||
|
||||
self._migrations: list[Type[MigrationABC]] = MigrationABC.__subclasses__()
|
||||
self._migrations = List(type, MigrationABC.__subclasses__()).order_by(lambda x: x.name)
|
||||
|
||||
def migrate(self):
|
||||
self._logger.info(__name__, f"Running Migrations")
|
||||
@@ -31,11 +32,10 @@ class MigrationService:
|
||||
# there is a table named "tableName"
|
||||
self._logger.trace(__name__, f"Running SQL Command: {MigrationHistory.get_select_by_id_string(migration_id)}")
|
||||
migration_from_db = self._db.select(MigrationHistory.get_select_by_id_string(migration_id))
|
||||
self._logger.trace(__name__, str(migration_from_db))
|
||||
if migration_from_db is not None and len(migration_from_db) > 0:
|
||||
continue
|
||||
|
||||
self._logger.debug(__name__, f"Running Migration {migration}")
|
||||
self._logger.debug(__name__, f"Running Migration {migration_id}")
|
||||
migration_as_service: MigrationABC = self._services.get_service(migration)
|
||||
migration_as_service.upgrade()
|
||||
self._cursor.execute(MigrationHistory(migration_id).insert_string)
|
||||
|
@@ -1,15 +1,16 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.model.server import Server
|
||||
|
||||
|
||||
class ServerRepositoryService(ServerRepositoryABC):
|
||||
|
||||
def __init__(self, logger: LoggerABC, db_context: DatabaseContextABC):
|
||||
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
|
@@ -1,18 +1,18 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.user_joined_server_repository_abc import \
|
||||
UserJoinedServerRepositoryABC
|
||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_data.model.user import User
|
||||
from bot_data.model.user_joined_server import UserJoinedServer
|
||||
|
||||
|
||||
class UserJoinedServerRepositoryService(UserJoinedServerRepositoryABC):
|
||||
|
||||
def __init__(self, logger: LoggerABC, db_context: DatabaseContextABC, users: UserRepositoryABC):
|
||||
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, users: UserRepositoryABC):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
|
@@ -1,17 +1,17 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_query.extension import List, IterableABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
|
||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
|
||||
|
||||
from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
|
||||
|
||||
|
||||
class UserJoinedVoiceChannelRepositoryService(UserJoinedVoiceChannelRepositoryABC):
|
||||
|
||||
def __init__(self, logger: LoggerABC, db_context: DatabaseContextABC, users: UserRepositoryABC):
|
||||
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, users: UserRepositoryABC):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
|
@@ -1,8 +1,9 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_query.extension import List
|
||||
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||
from bot_data.model.user import User
|
||||
@@ -10,7 +11,7 @@ from bot_data.model.user import User
|
||||
|
||||
class UserRepositoryService(UserRepositoryABC):
|
||||
|
||||
def __init__(self, logger: LoggerABC, db_context: DatabaseContextABC, servers: ServerRepositoryABC):
|
||||
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC, servers: ServerRepositoryABC):
|
||||
self._logger = logger
|
||||
self._context = db_context
|
||||
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'modules.admin'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -16,10 +16,10 @@
|
||||
"LicenseName": "",
|
||||
"LicenseDescription": "",
|
||||
"Dependencies": [
|
||||
"cpl-core>=2022.7.0.post5"
|
||||
"cpl-core>=2022.10.0.post5"
|
||||
],
|
||||
"DevDependencies": [
|
||||
"cpl-cli>=2022.7.0.post2"
|
||||
"cpl-cli>=2022.10.0"
|
||||
],
|
||||
"PythonVersion": ">=3.10.4",
|
||||
"PythonPath": {
|
||||
|
24
src/modules/admin/admin_module.py
Normal file
24
src/modules/admin/admin_module.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from modules.admin.command.restart_command import RestartCommand
|
||||
from modules.admin.command.shutdown_command import ShutdownCommand
|
||||
|
||||
|
||||
class AdminModule(ModuleABC):
|
||||
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.admin_module)
|
||||
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
# commands
|
||||
self._dc.add_command(RestartCommand)
|
||||
self._dc.add_command(ShutdownCommand)
|
||||
# events
|
@@ -15,7 +15,7 @@ __title__ = 'modules.admin.command'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -1,106 +0,0 @@
|
||||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
|
||||
import requests
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
from discord.ext import commands
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.configuration.bot_settings import BotSettings
|
||||
|
||||
|
||||
class DeployCommand(DiscordCommandABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
config: ConfigurationABC,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
translate: TranslatePipe,
|
||||
bot_settings: BotSettings,
|
||||
env: ApplicationEnvironmentABC
|
||||
):
|
||||
DiscordCommandABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
self._config = config
|
||||
self._message_service = message_service
|
||||
self._bot = bot
|
||||
self._client_utils = client_utils
|
||||
self._t = translate
|
||||
self._bot_settings = bot_settings
|
||||
self._env = env
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.command()
|
||||
@commands.dm_only()
|
||||
async def deploy(self, ctx: Context, old_version: str):
|
||||
self._logger.debug(__name__, f'Received command deploy {ctx}')
|
||||
|
||||
if ctx.author.id not in self._bot_settings.technicians:
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
|
||||
self._logger.trace(__name__, f'Finished deploy command')
|
||||
return
|
||||
|
||||
blacklist = ['venv', 'start', 'latest']
|
||||
|
||||
if old_version in blacklist:
|
||||
raise Exception(self._t.transform('common.errors.bad_argument'))
|
||||
|
||||
if len(ctx.message.attachments) > 1:
|
||||
raise IndexError(self._t.transform('common.errors.too_many_arguments'))
|
||||
|
||||
if len(ctx.message.attachments) < 1:
|
||||
raise IndexError(self._t.transform('common.errors.missing_required_argument'))
|
||||
|
||||
try:
|
||||
attachment_url = ctx.message.attachments[0].url
|
||||
file_request = requests.get(attachment_url)
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, f'An error occurred downloading the zip file', e)
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.command_error'))
|
||||
return
|
||||
|
||||
try:
|
||||
self._logger.debug(__name__, f'Deploying files to {self._bot_settings.deploy_file_path}/latest')
|
||||
deploy_path = f'{self._bot_settings.deploy_file_path}/latest'
|
||||
deploy_old_path = f'{self._bot_settings.deploy_file_path}/{old_version}'
|
||||
|
||||
if os.path.exists(deploy_path):
|
||||
self._logger.debug(__name__, f'Moving files of {self._bot_settings.deploy_file_path}/latest to {self._bot_settings.deploy_file_path}/{old_version}')
|
||||
shutil.move(deploy_path, deploy_old_path)
|
||||
os.makedirs(deploy_path)
|
||||
|
||||
file = zipfile.ZipFile(BytesIO(file_request.content))
|
||||
file.extractall(deploy_path)
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, f'An error occurred extracting the zip file', e)
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.command_error'), without_tracking=True)
|
||||
return
|
||||
|
||||
try:
|
||||
shutil.copy(f'{deploy_old_path}/bot/config/appsettings.{self._env.host_name}.json', f'{deploy_path}/bot/config/appsettings.{self._env.host_name}.json')
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, f'An error occurred copying config file', e)
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.command_error'), without_tracking=True)
|
||||
return
|
||||
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.admin.deploy_message'), without_tracking=True)
|
||||
|
||||
self._config.add_configuration('IS_RESTART', 'true')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.admin.restart_message'), without_tracking=True)
|
||||
await self._bot.stop_async()
|
||||
|
||||
self._logger.trace(__name__, f'Finished deploy command')
|
@@ -1,5 +1,7 @@
|
||||
import asyncio
|
||||
|
||||
import discord
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
@@ -8,6 +10,8 @@ from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.configuration.bot_settings import BotSettings
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||
|
||||
|
||||
@@ -15,13 +19,14 @@ class RestartCommand(DiscordCommandABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
logger: CommandLogger,
|
||||
config: ConfigurationABC,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
translate: TranslatePipe,
|
||||
permissions: PermissionServiceABC,
|
||||
settings: BotSettings
|
||||
):
|
||||
DiscordCommandABC.__init__(self)
|
||||
|
||||
@@ -32,13 +37,17 @@ class RestartCommand(DiscordCommandABC):
|
||||
self._client_utils = client_utils
|
||||
self._t = translate
|
||||
self._permissions = permissions
|
||||
self._settings = settings
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.guild_only()
|
||||
async def restart(self, ctx: Context):
|
||||
self._logger.debug(__name__, f'Received command restart {ctx}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
self._client_utils.received_command(ctx.guild.id)
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
@@ -47,6 +56,8 @@ class RestartCommand(DiscordCommandABC):
|
||||
return
|
||||
|
||||
self._config.add_configuration('IS_RESTART', 'true')
|
||||
await self._client_utils.presence_game('common.presence.restart')
|
||||
await asyncio.sleep(self._settings.wait_for_restart)
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.admin.restart_message'))
|
||||
await self._bot.stop_async()
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import asyncio
|
||||
|
||||
import discord
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
@@ -8,6 +10,8 @@ from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.configuration.bot_settings import BotSettings
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||
|
||||
|
||||
@@ -15,13 +19,14 @@ class ShutdownCommand(DiscordCommandABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
logger: CommandLogger,
|
||||
config: ConfigurationABC,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
translate: TranslatePipe,
|
||||
permissions: PermissionServiceABC,
|
||||
settings: BotSettings
|
||||
):
|
||||
DiscordCommandABC.__init__(self)
|
||||
|
||||
@@ -32,13 +37,17 @@ class ShutdownCommand(DiscordCommandABC):
|
||||
self._client_utils = client_utils
|
||||
self._t = translate
|
||||
self._permissions = permissions
|
||||
self._settings = settings
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.guild_only()
|
||||
async def shutdown(self, ctx: Context):
|
||||
self._logger.debug(__name__, f'Received command shutdown {ctx}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
self._client_utils.received_command(ctx.guild.id)
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
@@ -46,7 +55,9 @@ class ShutdownCommand(DiscordCommandABC):
|
||||
self._logger.trace(__name__, f'Finished shutdown command')
|
||||
return
|
||||
|
||||
await self._client_utils.presence_game('common.presence.shutdown')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.admin.shutdown_message'))
|
||||
await asyncio.sleep(self._settings.wait_for_shutdown)
|
||||
await self._bot.stop_async()
|
||||
|
||||
self._logger.trace(__name__, f'Finished shutdown command')
|
||||
|
26
src/modules/auto_role/__init__.py
Normal file
26
src/modules/auto_role/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'modules.auto_role'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
46
src/modules/auto_role/auto-role.json
Normal file
46
src/modules/auto_role/auto-role.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"ProjectSettings": {
|
||||
"Name": "auto-role",
|
||||
"Version": {
|
||||
"Major": "0",
|
||||
"Minor": "0",
|
||||
"Micro": "0"
|
||||
},
|
||||
"Author": "",
|
||||
"AuthorEmail": "",
|
||||
"Description": "",
|
||||
"LongDescription": "",
|
||||
"URL": "",
|
||||
"CopyrightDate": "",
|
||||
"CopyrightName": "",
|
||||
"LicenseName": "",
|
||||
"LicenseDescription": "",
|
||||
"Dependencies": [
|
||||
"cpl-core>=2022.10.0.post5"
|
||||
],
|
||||
"DevDependencies": [
|
||||
"cpl-cli>=2022.10.0"
|
||||
],
|
||||
"PythonVersion": ">=3.10.4",
|
||||
"PythonPath": {
|
||||
"linux": ""
|
||||
},
|
||||
"Classifiers": []
|
||||
},
|
||||
"BuildSettings": {
|
||||
"ProjectType": "library",
|
||||
"SourcePath": "",
|
||||
"OutputPath": "../../dist",
|
||||
"Main": "admin.main",
|
||||
"EntryPoint": "admin",
|
||||
"IncludePackageData": false,
|
||||
"Included": [],
|
||||
"Excluded": [
|
||||
"*/__pycache__",
|
||||
"*/logs",
|
||||
"*/tests"
|
||||
],
|
||||
"PackageData": {},
|
||||
"ProjectReferences": []
|
||||
}
|
||||
}
|
29
src/modules/auto_role/auto_role_module.py
Normal file
29
src/modules/auto_role/auto_role_module.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from modules.auto_role.command.auto_role_group import AutoRoleGroup
|
||||
from modules.auto_role.events.auto_role_on_raw_reaction_add import AutoRoleOnRawReactionAddEvent
|
||||
from modules.auto_role.events.auto_role_on_raw_reaction_remove import AutoRoleOnRawReactionRemoveEvent
|
||||
from modules.auto_role.helper.reaction_handler import ReactionHandler
|
||||
|
||||
|
||||
class AutoRoleModule(ModuleABC):
|
||||
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.auto_role_module)
|
||||
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_transient(ReactionHandler)
|
||||
# commands
|
||||
self._dc.add_command(AutoRoleGroup)
|
||||
# events
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_raw_reaction_add.value, AutoRoleOnRawReactionAddEvent)
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_raw_reaction_remove.value, AutoRoleOnRawReactionRemoveEvent)
|
26
src/modules/auto_role/command/__init__.py
Normal file
26
src/modules/auto_role/command/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'modules.auto_role.command'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
304
src/modules/auto_role/command/auto_role_group.py
Normal file
304
src/modules/auto_role/command/auto_role_group.py
Normal file
@@ -0,0 +1,304 @@
|
||||
from typing import List as TList, Optional
|
||||
|
||||
import discord
|
||||
from cpl_core.database.context import DatabaseContextABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.container import TextChannel
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_query.extension import List
|
||||
from cpl_translation import TranslatePipe
|
||||
from discord import app_commands
|
||||
from discord.ext import commands
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.model.auto_role import AutoRole
|
||||
from bot_data.model.auto_role_rule import AutoRoleRule
|
||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||
|
||||
|
||||
class AutoRoleGroup(DiscordCommandABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: CommandLogger,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
translate: TranslatePipe,
|
||||
servers: ServerRepositoryABC,
|
||||
auto_roles: AutoRoleRepositoryABC,
|
||||
db_context: DatabaseContextABC,
|
||||
permission_service: PermissionServiceABC,
|
||||
):
|
||||
DiscordCommandABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
self._message_service = message_service
|
||||
self._bot = bot
|
||||
self._client_utils = client_utils
|
||||
self._t = translate
|
||||
self._servers = servers
|
||||
self._auto_roles = auto_roles
|
||||
self._db_context = db_context
|
||||
self._permissions = permission_service
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.hybrid_group(name="auto-role")
|
||||
@commands.guild_only()
|
||||
async def auto_role(self, ctx: Context):
|
||||
pass
|
||||
|
||||
@auto_role.command(alias='auto-roles')
|
||||
@commands.guild_only()
|
||||
async def list(self, ctx: Context, wait: int = None):
|
||||
self._logger.debug(__name__, f'Received command auto-role list {ctx}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role list')
|
||||
return
|
||||
|
||||
embed = discord.Embed(
|
||||
title=self._t.transform('modules.auto_role.list.title'),
|
||||
description=self._t.transform('modules.auto_role.list.description'),
|
||||
color=int('ef9d0d', 16)
|
||||
)
|
||||
auto_roles = self._auto_roles.get_auto_roles()
|
||||
if auto_roles.count() < 1:
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.error.nothing_found'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role list')
|
||||
return
|
||||
|
||||
auto_role_id = ''
|
||||
message_id = ''
|
||||
for auto_role in auto_roles:
|
||||
auto_role_id += f'\n{auto_role.auto_role_id}'
|
||||
message_id += f'\n{auto_role.discord_message_id}'
|
||||
|
||||
embed.add_field(name=self._t.transform('modules.auto_role.list.auto_role_id'), value=auto_role_id, inline=True)
|
||||
embed.add_field(name=self._t.transform('modules.auto_role.list.message_id'), value=message_id, inline=True)
|
||||
await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait)
|
||||
self._logger.trace(__name__, f'Finished command auto-role list')
|
||||
|
||||
@auto_role.command()
|
||||
@commands.guild_only()
|
||||
async def add(self, ctx: Context, channel: discord.TextChannel, message_id: str):
|
||||
self._logger.debug(__name__, f'Received command auto-role add {ctx} {message_id}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role add')
|
||||
return
|
||||
|
||||
message = List(discord.Message, [message async for message in channel.history(limit=50)]).where(lambda m: m.id == int(message_id)).single_or_default()
|
||||
if message is None:
|
||||
self._logger.debug(__name__, f'Message with id {message_id} not found in {channel.name}')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.error.not_found').format(message_id, channel.name))
|
||||
self._logger.trace(__name__, f'Finished command auto-role add')
|
||||
return
|
||||
|
||||
if self._auto_roles.find_auto_role_by_message_id(int(message_id)) is not None:
|
||||
self._logger.debug(__name__, f'auto-role for message {message_id} already exists')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.error.already_exists').format(message_id))
|
||||
self._logger.trace(__name__, f'Finished command auto-role add')
|
||||
return
|
||||
|
||||
server_id = self._servers.get_server_by_discord_id(ctx.guild.id).server_id
|
||||
self._auto_roles.add_auto_role(AutoRole(server_id, int(message_id)))
|
||||
self._db_context.save_changes()
|
||||
self._logger.info(__name__, f'Saved auto-role for message {message_id} at server {server_id}')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.success').format(message_id))
|
||||
self._logger.trace(__name__, f'Finished command auto-role add')
|
||||
|
||||
@add.autocomplete('message_id')
|
||||
async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
channel = discord.utils.get(interaction.guild.text_channels, id=interaction.channel_id)
|
||||
try:
|
||||
channel_from_data = interaction.data['options'][0]['options'][0]['value']
|
||||
found_channel = discord.utils.get(interaction.guild.text_channels, id=int(channel_from_data))
|
||||
if found_channel is not None:
|
||||
channel = found_channel
|
||||
finally:
|
||||
pass
|
||||
|
||||
messages = [message async for message in channel.history(limit=10)]
|
||||
return [app_commands.Choice(name=f'{message.author}@{message.created_at}', value=str(message.id)) for message in messages if current in str(message.id)]
|
||||
|
||||
@auto_role.command()
|
||||
@commands.guild_only()
|
||||
async def remove(self, ctx: Context, auto_role: int):
|
||||
self._logger.debug(__name__, f'Received command auto-role remove {ctx} {auto_role}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role remove')
|
||||
return
|
||||
|
||||
auto_role_from_db = self._auto_roles.find_auto_role_by_id(auto_role)
|
||||
if auto_role_from_db is None:
|
||||
self._logger.debug(__name__, f'auto-role {auto_role} not found')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.error.not_found').format(auto_role))
|
||||
self._logger.trace(__name__, f'Finished command auto-role remove')
|
||||
return
|
||||
|
||||
for rule in self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_from_db.auto_role_id):
|
||||
self._auto_roles.delete_auto_role_rule(rule)
|
||||
self._logger.info(__name__, f'Removed auto-role rule {rule.role_id}')
|
||||
|
||||
self._auto_roles.delete_auto_role(auto_role_from_db)
|
||||
self._db_context.save_changes()
|
||||
self._logger.info(__name__, f'Removed auto-role {auto_role}')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.success').format(auto_role))
|
||||
self._logger.trace(__name__, f'Finished command auto-role remove')
|
||||
|
||||
@remove.autocomplete('auto_role')
|
||||
async def remove_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
auto_roles = self._auto_roles.get_auto_roles().select(lambda x: x.auto_role_id)
|
||||
return [app_commands.Choice(name=auto_role, value=auto_role) for auto_role in auto_roles]
|
||||
|
||||
@auto_role.group()
|
||||
@commands.guild_only()
|
||||
async def rule(self, ctx: Context):
|
||||
pass
|
||||
|
||||
@rule.command(alias='rules')
|
||||
@commands.guild_only()
|
||||
async def list(self, ctx: Context, auto_role: int, wait: int = None):
|
||||
self._logger.debug(__name__, f'Received command auto-role rule list {ctx}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule list')
|
||||
return
|
||||
|
||||
embed = discord.Embed(
|
||||
title=self._t.transform('modules.auto_role.list.title'),
|
||||
description=self._t.transform('modules.auto_role.list.description'),
|
||||
color=int('ef9d0d', 16)
|
||||
)
|
||||
rules = self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role)
|
||||
if rules.count() < 1:
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.error.id_not_found'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule list')
|
||||
return
|
||||
|
||||
auto_role_rule_id = ''
|
||||
emoji = ''
|
||||
role = ''
|
||||
for rule in rules:
|
||||
auto_role_rule_id += f'\n{rule.role_id}'
|
||||
emoji += f'\n{rule.emoji_name}'
|
||||
role += f'\n{ctx.guild.get_role(rule.role_id)}'
|
||||
|
||||
embed.add_field(name=self._t.transform('modules.auto_role.rule.list.auto_role_rule_id'), value=auto_role_rule_id, inline=True)
|
||||
embed.add_field(name=self._t.transform('modules.auto_role.rule.list.emoji'), value=emoji, inline=True)
|
||||
embed.add_field(name=self._t.transform('modules.auto_role.rule.list.role'), value=role, inline=True)
|
||||
await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait)
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule list')
|
||||
|
||||
@list.autocomplete('auto_role')
|
||||
async def list_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
auto_roles = self._auto_roles.get_auto_roles().select(lambda x: x.auto_role_id)
|
||||
return [app_commands.Choice(name=auto_role, value=auto_role) for auto_role in auto_roles]
|
||||
|
||||
@rule.command()
|
||||
@commands.guild_only()
|
||||
async def add(self, ctx: Context, auto_role: int, emoji_name: str, role_id: str):
|
||||
self._logger.debug(__name__, f'Received command auto-role add {ctx} {auto_role}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule add')
|
||||
return
|
||||
|
||||
emoji = discord.utils.get(self._bot.emojis, name=emoji_name)
|
||||
if emoji is None:
|
||||
self._logger.debug(__name__, f'auto-role rule add emoji {emoji_name} not found')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.add.error.emoji_not_found').format(emoji_name, auto_role))
|
||||
self._logger.trace(__name__, f'Finished command auto-role add')
|
||||
return
|
||||
|
||||
role = ctx.guild.get_role(int(role_id))
|
||||
if role is None:
|
||||
self._logger.debug(__name__, f'auto-role rule add role {role_id} not found')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.add.error.role_not_found').format(role_id, auto_role))
|
||||
self._logger.trace(__name__, f'Finished command auto-role add')
|
||||
return
|
||||
|
||||
auto_role_from_db = self._auto_roles.get_auto_role_by_id(auto_role)
|
||||
if auto_role_from_db is None:
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.error.not_found').format(auto_role))
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule add')
|
||||
return
|
||||
|
||||
if self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role).where(lambda r: r.emoji_name == emoji.name and int(role_id) == role.id).count() > 0:
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.add.error.already_exists').format(auto_role))
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule add')
|
||||
return
|
||||
|
||||
self._auto_roles.add_auto_role_rule(AutoRoleRule(auto_role, emoji_name, int(role_id)))
|
||||
self._db_context.save_changes()
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.add.success').format(emoji, role.name, auto_role))
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule add')
|
||||
|
||||
@add.autocomplete('auto_role')
|
||||
async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
auto_roles = self._auto_roles.get_auto_roles().select(lambda x: x.auto_role_id)
|
||||
return [app_commands.Choice(name=auto_role, value=auto_role) for auto_role in auto_roles]
|
||||
|
||||
@add.autocomplete('emoji_name')
|
||||
async def add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
emojis = interaction.guild.emojis
|
||||
return [app_commands.Choice(name=emoji.name, value=emoji.name) for emoji in emojis]
|
||||
|
||||
@add.autocomplete('role_id')
|
||||
async def rule_add_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
roles = interaction.guild.roles
|
||||
return [app_commands.Choice(name=role.name, value=str(role.id)) for role in roles]
|
||||
|
||||
@rule.command()
|
||||
@commands.guild_only()
|
||||
async def remove(self, ctx: Context, auto_role_rule: int):
|
||||
self._logger.debug(__name__, f'Received command auto-role remove {ctx} {auto_role_rule}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
|
||||
if not self._permissions.is_member_moderator(ctx.author):
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message'))
|
||||
self._logger.trace(__name__, f'Finished command auto-role remove')
|
||||
return
|
||||
|
||||
auto_role_from_db = self._auto_roles.get_auto_role_rule_by_id(auto_role_rule)
|
||||
if auto_role_from_db is None:
|
||||
self._logger.debug(__name__, f'auto-role rule {auto_role_rule} not found')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.remove.error.not_found').format(auto_role_rule))
|
||||
self._logger.trace(__name__, f'Finished command auto-role rule remove')
|
||||
return
|
||||
|
||||
self._auto_roles.delete_auto_role_rule(auto_role_from_db)
|
||||
self._db_context.save_changes()
|
||||
self._logger.info(__name__, f'Removed auto-role rule {auto_role_rule}')
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.auto_role.rule.remove.success').format(auto_role_rule))
|
||||
self._logger.trace(__name__, f'Finished command auto-role remove')
|
||||
|
||||
@remove.autocomplete('auto_role_rule')
|
||||
async def remove_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]:
|
||||
rules = self._auto_roles.get_auto_role_rules()
|
||||
return [app_commands.Choice(name=f'{rule.auto_role_rule_id} {rule.emoji_name} {interaction.guild.get_role(int(rule.role_id))}', value=rule.auto_role_rule_id) for rule in
|
||||
rules]
|
26
src/modules/auto_role/events/__init__.py
Normal file
26
src/modules/auto_role/events/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'modules.auto_role.events'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
@@ -0,0 +1,34 @@
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.events.on_raw_reaction_add_abc import OnRawReactionAddABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from discord import RawReactionActionEvent
|
||||
|
||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from modules.auto_role.helper.reaction_handler import ReactionHandler
|
||||
|
||||
|
||||
class AutoRoleOnRawReactionAddEvent(OnRawReactionAddABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
servers: ServerRepositoryABC,
|
||||
auto_roles: AutoRoleRepositoryABC,
|
||||
reaction_handler: ReactionHandler
|
||||
):
|
||||
OnRawReactionAddABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
self._servers = servers
|
||||
self._auto_roles = auto_roles
|
||||
self._reaction_handler = reaction_handler
|
||||
|
||||
async def on_raw_reaction_add(self, payload: RawReactionActionEvent):
|
||||
self._logger.debug(__name__, f'Module {type(self)} started')
|
||||
|
||||
await self._reaction_handler.handle(payload, 'add')
|
||||
|
||||
self._logger.debug(__name__, f'Module {type(self)} stopped')
|
@@ -0,0 +1,34 @@
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.events.on_raw_reaction_remove_abc import OnRawReactionRemoveABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from discord import RawReactionActionEvent
|
||||
|
||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from modules.auto_role.helper.reaction_handler import ReactionHandler
|
||||
|
||||
|
||||
class AutoRoleOnRawReactionRemoveEvent(OnRawReactionRemoveABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
servers: ServerRepositoryABC,
|
||||
auto_roles: AutoRoleRepositoryABC,
|
||||
reaction_handler: ReactionHandler
|
||||
):
|
||||
OnRawReactionRemoveABC.__init__(self)
|
||||
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
self._servers = servers
|
||||
self._auto_roles = auto_roles
|
||||
self._reaction_handler = reaction_handler
|
||||
|
||||
async def on_raw_reaction_remove(self, payload: RawReactionActionEvent):
|
||||
self._logger.debug(__name__, f'Module {type(self)} started')
|
||||
|
||||
await self._reaction_handler.handle(payload, 'remove')
|
||||
|
||||
self._logger.debug(__name__, f'Module {type(self)} stopped')
|
26
src/modules/auto_role/helper/__init__.py
Normal file
26
src/modules/auto_role/helper/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
bot Keksdose bot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Discord bot for the Keksdose discord Server
|
||||
|
||||
:copyright: (c) 2022 sh-edraft.de
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'modules.auto_role.helper'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
70
src/modules/auto_role/helper/reaction_handler.py
Normal file
70
src/modules/auto_role/helper/reaction_handler.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import discord
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_query.extension import List
|
||||
from discord import RawReactionActionEvent
|
||||
|
||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.model.auto_role import AutoRole
|
||||
from bot_data.model.auto_role_rule import AutoRoleRule
|
||||
|
||||
|
||||
class ReactionHandler:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
servers: ServerRepositoryABC,
|
||||
auto_roles: AutoRoleRepositoryABC
|
||||
):
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
self._servers = servers
|
||||
self._auto_roles = auto_roles
|
||||
|
||||
self._message_ids = self._auto_roles.get_auto_roles().select(lambda x: x.discord_message_id)
|
||||
self._roles = self._auto_roles.get_auto_roles()
|
||||
|
||||
async def handle(self, payload: RawReactionActionEvent, r_type=None) -> None:
|
||||
self._logger.trace(__name__, f'Handle reaction {payload} {r_type}')
|
||||
if payload.message_id not in self._message_ids:
|
||||
self._logger.debug(__name__, f'Message not in auto-roles - skipping')
|
||||
return
|
||||
|
||||
guild = self._bot.get_guild(payload.guild_id)
|
||||
user = guild.get_member(payload.user_id)
|
||||
if user is None:
|
||||
self._logger.warn(__name__, f'User {payload.user_id} in {guild.name} not found - skipping')
|
||||
return
|
||||
|
||||
if user.bot:
|
||||
self._logger.debug(__name__, f'User is bot - skipping')
|
||||
return
|
||||
|
||||
emoji = payload.emoji.name
|
||||
auto_role: AutoRole = self._roles.where(lambda x: x.discord_message_id == payload.message_id).single_or_default()
|
||||
if auto_role is None:
|
||||
self._logger.debug(__name__, f'auto-role for message not found - skipping')
|
||||
return
|
||||
|
||||
rules: List[AutoRoleRule] = self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role.auto_role_id)
|
||||
if rules.count() == 0:
|
||||
self._logger.debug(__name__, f'auto-role rules not found - skipping')
|
||||
return
|
||||
|
||||
for rule in rules:
|
||||
if emoji != rule.emoji_name:
|
||||
continue
|
||||
|
||||
if r_type == 'add':
|
||||
role = guild.get_role(rule.role_id)
|
||||
self._logger.debug(__name__, f'Assign role {role.name} to {user.name}')
|
||||
await user.add_roles(role)
|
||||
elif r_type == 'remove':
|
||||
role = guild.get_role(rule.role_id)
|
||||
self._logger.debug(__name__, f'Remove role {role.name} to {user.name}')
|
||||
await user.remove_roles(role)
|
||||
else:
|
||||
self._logger.warn(__name__, f'Invalid reaction type {r_type}')
|
@@ -15,7 +15,7 @@ __title__ = 'modules.base'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'modules.base.abc'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -16,10 +16,10 @@
|
||||
"LicenseName": "",
|
||||
"LicenseDescription": "",
|
||||
"Dependencies": [
|
||||
"cpl-core>=2022.7.0.post2"
|
||||
"cpl-core>=2022.10.0.post2"
|
||||
],
|
||||
"DevDependencies": [
|
||||
"cpl-cli>=2022.7.0.post2"
|
||||
"cpl-cli>=2022.10.0"
|
||||
],
|
||||
"PythonVersion": ">=3.10.4",
|
||||
"PythonPath": {
|
||||
|
44
src/modules/base/base_module.py
Normal file
44
src/modules/base/base_module.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||
from cpl_core.environment import ApplicationEnvironmentABC
|
||||
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
|
||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||
|
||||
from bot_core.abc.module_abc import ModuleABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from modules.base.abc.base_helper_abc import BaseHelperABC
|
||||
from modules.base.command.afk_command import AFKCommand
|
||||
from modules.base.command.help_command import HelpCommand
|
||||
from modules.base.command.info_command import InfoCommand
|
||||
from modules.base.command.ping_command import PingCommand
|
||||
from modules.base.events.base_on_command_error_event import BaseOnCommandErrorEvent
|
||||
from modules.base.events.base_on_command_event import BaseOnCommandEvent
|
||||
from modules.base.events.base_on_member_join_event import BaseOnMemberJoinEvent
|
||||
from modules.base.events.base_on_member_remove_event import BaseOnMemberRemoveEvent
|
||||
from modules.base.events.base_on_message_event import BaseOnMessageEvent
|
||||
from modules.base.events.base_on_voice_state_update_event import BaseOnVoiceStateUpdateEvent
|
||||
from modules.base.service.base_helper_service import BaseHelperService
|
||||
|
||||
|
||||
class BaseModule(ModuleABC):
|
||||
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.base_module)
|
||||
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_transient(BaseHelperABC, BaseHelperService)
|
||||
# commands
|
||||
self._dc.add_command(AFKCommand)
|
||||
self._dc.add_command(HelpCommand)
|
||||
self._dc.add_command(InfoCommand)
|
||||
self._dc.add_command(PingCommand)
|
||||
# events
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_command.value, BaseOnCommandEvent)
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_command_error.value, BaseOnCommandErrorEvent)
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_member_join.value, BaseOnMemberJoinEvent)
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_member_remove.value, BaseOnMemberRemoveEvent)
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_message.value, BaseOnMessageEvent)
|
||||
self._dc.add_event(DiscordEventTypesEnum.on_voice_state_update.value, BaseOnVoiceStateUpdateEvent)
|
@@ -15,7 +15,7 @@ __title__ = 'modules.base.command'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -1,5 +1,4 @@
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
@@ -9,6 +8,7 @@ from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
from modules.base.configuration.base_server_settings import BaseServerSettings
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class AFKCommand(DiscordCommandABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
logger: CommandLogger,
|
||||
config: ConfigurationABC,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
@@ -34,10 +34,12 @@ class AFKCommand(DiscordCommandABC):
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.guild_only()
|
||||
async def afk(self, ctx: Context):
|
||||
self._logger.debug(__name__, f'Received command afk {ctx}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
self._client_utils.received_command(ctx.guild.id)
|
||||
settings: BaseServerSettings = self._config.get_configuration(f'BaseServerSettings_{ctx.guild.id}')
|
||||
|
||||
|
@@ -1,12 +1,16 @@
|
||||
from typing import List
|
||||
|
||||
import discord
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from discord import app_commands
|
||||
from discord.ext import commands
|
||||
from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
from modules.base.configuration.base_server_settings import BaseServerSettings
|
||||
|
||||
|
||||
@@ -15,7 +19,7 @@ class HelpCommand(DiscordCommandABC):
|
||||
def __init__(
|
||||
self,
|
||||
config: ConfigurationABC,
|
||||
logger: LoggerABC,
|
||||
logger: CommandLogger,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC
|
||||
@@ -30,12 +34,19 @@ class HelpCommand(DiscordCommandABC):
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.guild_only()
|
||||
async def help(self, ctx: Context, persistent_flag: str = None):
|
||||
self._logger.debug(__name__, f'Received command help {ctx}:{persistent_flag}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
self._client_utils.received_command(ctx.guild.id)
|
||||
settings: BaseServerSettings = self._config.get_configuration(f'BaseServerSettings_{ctx.guild.id}')
|
||||
is_persistent = persistent_flag == '--stay'
|
||||
await self._message_service.send_ctx_msg(ctx, settings.help_command_reference_url, is_persistent=is_persistent)
|
||||
self._logger.trace(__name__, f'Finished help command')
|
||||
|
||||
@help.autocomplete('persistent_flag')
|
||||
async def help_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
|
||||
flags = ['--stay']
|
||||
return [app_commands.Choice(name=key, value=key) for key in flags]
|
||||
|
@@ -2,7 +2,6 @@ from datetime import datetime
|
||||
|
||||
import discord
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
@@ -12,6 +11,7 @@ from discord.ext.commands import Context
|
||||
import bot
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
|
||||
|
||||
class InfoCommand(DiscordCommandABC):
|
||||
@@ -19,7 +19,7 @@ class InfoCommand(DiscordCommandABC):
|
||||
def __init__(
|
||||
self,
|
||||
config: ConfigurationABC,
|
||||
logger: LoggerABC,
|
||||
logger: CommandLogger,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
@@ -36,10 +36,12 @@ class InfoCommand(DiscordCommandABC):
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.guild_only()
|
||||
async def info(self, ctx: Context, *, wait: int = None):
|
||||
self._logger.debug(__name__, f'Received command info {ctx},{wait}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
self._client_utils.received_command(ctx.guild.id)
|
||||
client = self._client_utils.get_client(self._bot.user.id, ctx.guild.id)
|
||||
|
||||
@@ -58,7 +60,9 @@ class InfoCommand(DiscordCommandABC):
|
||||
embed.add_field(name=self._t.transform('modules.base.info.fields.deleted_message_count'), value=client.deleted_message_count, inline=False)
|
||||
embed.add_field(name=self._t.transform('modules.base.info.fields.received_command_count'), value=client.received_command_count)
|
||||
embed.add_field(name=self._t.transform('modules.base.info.fields.moved_users_count'), value=client.moved_users_count)
|
||||
modules = ['Base', 'BootLog', 'Database', 'Permission']
|
||||
from bot.module_list import ModuleList
|
||||
modules = ModuleList.get_modules()
|
||||
modules = modules.select(lambda x: x.__name__.replace('Module', ''))
|
||||
embed.add_field(name=self._t.transform('modules.base.info.fields.modules'), value='\n'.join(modules), inline=False)
|
||||
|
||||
await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait)
|
||||
|
@@ -1,4 +1,3 @@
|
||||
from cpl_core.logging import LoggerABC
|
||||
from cpl_discord.command import DiscordCommandABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from cpl_translation import TranslatePipe
|
||||
@@ -7,13 +6,14 @@ from discord.ext.commands import Context
|
||||
|
||||
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
|
||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
||||
from bot_core.logging.command_logger import CommandLogger
|
||||
|
||||
|
||||
class PingCommand(DiscordCommandABC):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
logger: LoggerABC,
|
||||
logger: CommandLogger,
|
||||
message_service: MessageServiceABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsServiceABC,
|
||||
@@ -29,10 +29,12 @@ class PingCommand(DiscordCommandABC):
|
||||
|
||||
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
|
||||
|
||||
@commands.command()
|
||||
@commands.hybrid_command()
|
||||
@commands.guild_only()
|
||||
async def ping(self, ctx: Context):
|
||||
self._logger.debug(__name__, f'Received command ping {ctx}')
|
||||
if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx):
|
||||
return
|
||||
self._client_utils.received_command(ctx.guild.id)
|
||||
await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.base.pong'))
|
||||
self._logger.trace(__name__, f'Finished ping command')
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'modules.base.configuration'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
@@ -2,6 +2,7 @@ import traceback
|
||||
|
||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
||||
from cpl_core.console import Console
|
||||
from cpl_query.extension import List
|
||||
|
||||
|
||||
class BaseServerSettings(ConfigurationModelABC):
|
||||
@@ -13,7 +14,9 @@ class BaseServerSettings(ConfigurationModelABC):
|
||||
self._max_voice_state_hours: int = 0
|
||||
self._xp_per_message: int = 0
|
||||
self._xp_per_ontime_hour: int = 0
|
||||
self._afk_channel_ids: list[int] = []
|
||||
self._afk_channel_ids: List[int] = List(int)
|
||||
self._afk_command_channel_id: int = 0
|
||||
self._help_command_reference_url: str = ''
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
@@ -32,7 +35,7 @@ class BaseServerSettings(ConfigurationModelABC):
|
||||
return self._xp_per_ontime_hour
|
||||
|
||||
@property
|
||||
def afk_channel_ids(self) -> list[int]:
|
||||
def afk_channel_ids(self) -> List[int]:
|
||||
return self._afk_channel_ids
|
||||
|
||||
@property
|
||||
|
@@ -15,7 +15,7 @@ __title__ = 'modules.base.events'
|
||||
__author__ = 'Sven Heidemann'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2022 sh-edraft.de'
|
||||
__version__ = '1.0.0.dev3'
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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='0', micro='0.dev3')
|
||||
version_info = VersionInfo(major='0', minor='2', micro='3')
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user