Compare commits
103 Commits
dd6b609094
...
1.2.1
Author | SHA1 | Date | |
---|---|---|---|
d2c37a0098 | |||
804aa0b9b8 | |||
692cf8de31 | |||
b15c3b7fa3 | |||
49121fd179 | |||
9bad75e7c2 | |||
7358b67072 | |||
1b0ba01258 | |||
6fc5ee3ed3 | |||
099707446d | |||
d6b7fd73df | |||
6bfb0ddbf9 | |||
e1b76fa628 | |||
e6f98def6a | |||
590479eee2 | |||
d25305be4a | |||
2889a97f17 | |||
b540821a32 | |||
5b43b72838 | |||
46cd33d194 | |||
1287829bdf | |||
c91c8b2bcd | |||
a5b4c4cd66 | |||
1688347367 | |||
6e79811bc9 | |||
e1258151de | |||
a7c833b9db | |||
2f161d2f43 | |||
0a5f23f1af | |||
23a3dbbc5e | |||
8975665407 | |||
90de90684c | |||
d1ecfe9603 | |||
f7f25e9428 | |||
6ae7ab5c5a | |||
315c90cacc | |||
2caa910613 | |||
8e55ebc4b7 | |||
665e524aa9 | |||
ae021ac7ea | |||
dcbb481b10 | |||
e6165caed9 | |||
58fdc9f48f | |||
1c02608410 | |||
5e0b322273 | |||
4f336bed05 | |||
99d476df86 | |||
81062e74d7 | |||
acae8ac891 | |||
e3dc0f725e | |||
40a7919a3f | |||
14d0e38c5d | |||
62649226ba | |||
0a04ad74d8 | |||
467050d87e | |||
e8f2a01851 | |||
f972055ebf | |||
9bbfe498cc | |||
b21c9f894f | |||
7a0f29f557 | |||
ed72620d33 | |||
b8356917b3 | |||
84fedfaa0b | |||
2d358188af | |||
79278d8f4b | |||
b943b9a7ed | |||
1c20bbed66 | |||
33006e3d01 | |||
90ae55c0d4 | |||
626d0891f9 | |||
09cccd1b89 | |||
940a2ed065 | |||
c2fa1a1c00 | |||
1f1b1f7b65 | |||
4b52995143 | |||
6a6d19686c | |||
798162fb62 | |||
74c71abea5 | |||
0e679eda32 | |||
403c169b71 | |||
a113e21e19 | |||
71c091c226 | |||
b8d27cc682 | |||
c9b967b9d0 | |||
410049be6e | |||
be6361f619 | |||
3a7daf8b42 | |||
f435d3dd48 | |||
eb32bec43c | |||
232429a77d | |||
0946734633 | |||
ea1472a9eb | |||
f710f6ad6c | |||
030fedfcfb | |||
bd1d230f67 | |||
dcafa63d74 | |||
3a42b42dbf | |||
4747f23202 | |||
5057cbed16 | |||
7aff767a4b | |||
61bdc8a52a | |||
5afd0fafa8 | |||
eeda0405f3 |
@@ -8,50 +8,56 @@ on:
|
||||
jobs:
|
||||
on-push-deploy_sh-edraft:
|
||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
||||
container: catthehacker/ubuntu:act-latest
|
||||
container: sh-edraft.de/act-runner:latest
|
||||
steps:
|
||||
- name: Setup Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10.12"
|
||||
- run: python -v
|
||||
|
||||
- name: Setup docker
|
||||
uses: https://github.com/papodaca/install-docker-action@main
|
||||
- run: docker -v
|
||||
|
||||
- name: Clone Repository
|
||||
uses: https://github.com/actions/checkout@v3
|
||||
|
||||
- name: Shutdown stack
|
||||
run: docker stack rm kdb_staging
|
||||
with:
|
||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
||||
submodules: true
|
||||
|
||||
- name: Prepare bot build
|
||||
run: |
|
||||
cd kdb-bot
|
||||
pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
||||
cd bot
|
||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
||||
cpl i
|
||||
|
||||
- name: Build docker bot
|
||||
run: |
|
||||
cd kdb-bot
|
||||
docker image prune -f
|
||||
cpl docker-build
|
||||
|
||||
- name: Setup node
|
||||
uses: https://github.com/actions/setup-node@v3
|
||||
|
||||
- name: Prepare web build
|
||||
run: |
|
||||
cd kdb-web
|
||||
cd web
|
||||
npm install -g ts-node
|
||||
npm i
|
||||
npm ci
|
||||
|
||||
- name: Shutdown stack
|
||||
run: docker stack rm sdb_dev
|
||||
|
||||
- name: Build docker bot
|
||||
run: |
|
||||
cd bot
|
||||
docker image prune -f
|
||||
cpl build
|
||||
docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-dev .
|
||||
|
||||
- name: Build docker web
|
||||
run: |
|
||||
cd kdb-web
|
||||
cd web
|
||||
docker image prune -f
|
||||
npm run docker-build
|
||||
cp src/favicon.dev.ico src/favicon.ico
|
||||
npm run build
|
||||
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-dev .
|
||||
|
||||
- name: Set version
|
||||
run: |
|
||||
cd bot/docker
|
||||
chmod +x ./set-docker-compose-image-version.sh
|
||||
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-dev sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-dev
|
||||
|
||||
- name: Deploy Stack to sh-edraft.de
|
||||
uses: https://github.com/kgierke/portainer-stack-deployment@v1
|
||||
@@ -60,6 +66,6 @@ jobs:
|
||||
portainer-username: "gitea_job"
|
||||
portainer-password: "${{ secrets.docker_job }}"
|
||||
portainer-endpoint: 2
|
||||
name: kdb_staging
|
||||
file: ./docker-compose.staging.yml
|
||||
name: sdb_dev
|
||||
file: bot/docker/docker-compose.dev.yml
|
||||
variables: '{}'
|
||||
|
@@ -1,5 +1,5 @@
|
||||
name: Deploy dev on push
|
||||
run-name: Deploy dev on push
|
||||
name: Deploy prod on push
|
||||
run-name: Deploy prod on push
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -8,50 +8,55 @@ on:
|
||||
jobs:
|
||||
on-push-deploy_sh-edraft:
|
||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
||||
container: catthehacker/ubuntu:act-latest
|
||||
container: sh-edraft.de/act-runner:latest
|
||||
steps:
|
||||
- name: Setup Python 3.10
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "3.10.12"
|
||||
- run: python -v
|
||||
|
||||
- name: Setup docker
|
||||
uses: https://github.com/papodaca/install-docker-action@main
|
||||
- run: docker -v
|
||||
|
||||
- name: Clone Repository
|
||||
uses: https://github.com/actions/checkout@v3
|
||||
|
||||
- name: Shutdown stack
|
||||
run: docker stack rm kdb_prod
|
||||
with:
|
||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
||||
submodules: true
|
||||
|
||||
- name: Prepare bot build
|
||||
run: |
|
||||
cd kdb-bot
|
||||
pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
||||
cd bot
|
||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
||||
cpl i
|
||||
|
||||
- name: Build docker bot
|
||||
run: |
|
||||
cd kdb-bot
|
||||
docker image prune -f
|
||||
cpl docker-build
|
||||
|
||||
- name: Setup node
|
||||
uses: https://github.com/actions/setup-node@v3
|
||||
|
||||
- name: Prepare web build
|
||||
run: |
|
||||
cd kdb-web
|
||||
cd web
|
||||
npm install -g ts-node
|
||||
npm i
|
||||
npm ci
|
||||
|
||||
- name: Shutdown stack
|
||||
run: docker stack rm sdb_prod
|
||||
|
||||
- name: Build docker bot
|
||||
run: |
|
||||
cd bot
|
||||
docker image prune -f
|
||||
cpl build
|
||||
docker build -t sh-edraft.de/sdb-bot:$(cpl gv) .
|
||||
|
||||
- name: Build docker web
|
||||
run: |
|
||||
cd kdb-web
|
||||
cd web
|
||||
docker image prune -f
|
||||
npm run docker-build
|
||||
npm run build
|
||||
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv) .
|
||||
|
||||
- name: Set version
|
||||
run: |
|
||||
cd bot/docker
|
||||
chmod +x ./set-docker-compose-image-version.sh
|
||||
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv) sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)
|
||||
|
||||
- name: Deploy Stack to sh-edraft.de
|
||||
uses: https://github.com/kgierke/portainer-stack-deployment@v1
|
||||
@@ -60,6 +65,6 @@ jobs:
|
||||
portainer-username: "gitea_job"
|
||||
portainer-password: "${{ secrets.docker_job }}"
|
||||
portainer-endpoint: 2
|
||||
name: kdb_prod
|
||||
file: ./docker-compose.yml
|
||||
name: sdb_prod
|
||||
file: bot/docker/docker-compose.yml
|
||||
variables: '{}'
|
||||
|
71
.gitea/workflows/deploy_staging.yaml
Normal file
71
.gitea/workflows/deploy_staging.yaml
Normal file
@@ -0,0 +1,71 @@
|
||||
name: Deploy staging on push
|
||||
run-name: Deploy staging on push
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- staging
|
||||
|
||||
jobs:
|
||||
on-push-deploy_sh-edraft:
|
||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
||||
container: sh-edraft.de/act-runner:latest
|
||||
steps:
|
||||
- name: Setup docker
|
||||
uses: https://github.com/papodaca/install-docker-action@main
|
||||
- run: docker -v
|
||||
|
||||
- name: Clone Repository
|
||||
uses: https://github.com/actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
||||
submodules: true
|
||||
|
||||
- name: Prepare bot build
|
||||
run: |
|
||||
cd bot
|
||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
||||
cpl i
|
||||
|
||||
- name: Setup node
|
||||
uses: https://github.com/actions/setup-node@v3
|
||||
|
||||
- name: Prepare web build
|
||||
run: |
|
||||
cd web
|
||||
npm install -g ts-node
|
||||
npm ci
|
||||
|
||||
- name: Shutdown stack
|
||||
run: docker stack rm sdb_staging
|
||||
|
||||
- name: Build docker bot
|
||||
run: |
|
||||
cd bot
|
||||
docker image prune -f
|
||||
cpl build
|
||||
docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-staging .
|
||||
|
||||
- name: Build docker web
|
||||
run: |
|
||||
cd web
|
||||
docker image prune -f
|
||||
cp src/favicon.staging.ico src/favicon.ico
|
||||
npm run build
|
||||
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-staging .
|
||||
|
||||
- name: Set version
|
||||
run: |
|
||||
cd bot/docker
|
||||
chmod +x ./set-docker-compose-image-version.sh
|
||||
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-staging sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-staging
|
||||
|
||||
- name: Deploy Stack to sh-edraft.de
|
||||
uses: https://github.com/kgierke/portainer-stack-deployment@v1
|
||||
with:
|
||||
portainer-url: "https://docker.sh-edraft.de"
|
||||
portainer-username: "gitea_job"
|
||||
portainer-password: "${{ secrets.docker_job }}"
|
||||
portainer-endpoint: 2
|
||||
name: sdb_staging
|
||||
file: bot/docker/docker-compose.staging.yml
|
||||
variables: '{}'
|
@@ -32,12 +32,12 @@
|
||||
"pre-build": "cpl set-version $ARGS; black ./;",
|
||||
"post-build": "cpl run post-build --dev; black ./;",
|
||||
"pre-prod": "cpl build",
|
||||
"prod": "export KDB_ENVIRONMENT=production; export KDB_NAME=KDB-Prod; cpl start;",
|
||||
"prod": "export SDB_ENVIRONMENT=production; export SDB_NAME=SDB-Prod; cpl start;",
|
||||
"pre-stage": "cpl build",
|
||||
"stage": "export KDB_ENVIRONMENT=staging; export KDB_NAME=KDB-Stage; cpl start;",
|
||||
"stage": "export SDB_ENVIRONMENT=staging; export SDB_NAME=SDB-Stage; cpl start;",
|
||||
"pre-dev": "cpl build",
|
||||
"dev": "export KDB_ENVIRONMENT=development; export KDB_NAME=KDB-Dev; cpl start;",
|
||||
"docker-build": "cpl build $ARGS; docker build -t sh-edraft.de/kdb-bot:$(cpl gv) .;",
|
||||
"dev": "export SDB_ENVIRONMENT=development; export SDB_NAME=SDB-Dev; cpl start;",
|
||||
"docker-build": "cpl build $ARGS; docker build -t sh-edraft.de/sdb-bot:$(cpl gv) .;",
|
||||
"dc-up": "docker-compose up -d",
|
||||
"dc-down": "docker-compose down",
|
||||
"docker": "cpl dc-down; cpl docker-build; cpl dc-up;"
|
||||
|
1
bot/docker
Submodule
1
bot/docker
Submodule
Submodule bot/docker added at 9c0dc59534
@@ -2,7 +2,7 @@
|
||||
FROM python:3.10.4-alpine
|
||||
|
||||
WORKDIR /app
|
||||
COPY ./dist/bot/build/kdb-bot/ .
|
||||
COPY ./dist/bot/build/bot/ .
|
||||
COPY ./dist/bot/build/requirements.txt .
|
||||
|
||||
RUN python -m pip install --upgrade pip
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -11,6 +11,7 @@ from bot_api.api_thread import ApiThread
|
||||
from bot_core.abc.task_abc import TaskABC
|
||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
||||
from bot_core.environment_variables import MAINTENANCE
|
||||
from bot_core.service.data_integrity_service import DataIntegrityService
|
||||
|
||||
|
||||
@@ -23,25 +24,17 @@ class Application(DiscordBotApplicationABC):
|
||||
|
||||
# cpl-core
|
||||
self._logger: LoggerABC = services.get_service(LoggerABC)
|
||||
self._data_integrity: DataIntegrityService = services.get_service(
|
||||
DataIntegrityService
|
||||
)
|
||||
self._data_integrity: DataIntegrityService = services.get_service(DataIntegrityService)
|
||||
# cpl-discord
|
||||
self._bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC)
|
||||
self._bot_settings: DiscordBotSettings = config.get_configuration(
|
||||
DiscordBotSettings
|
||||
)
|
||||
self._bot_settings: DiscordBotSettings = config.get_configuration(DiscordBotSettings)
|
||||
# cpl-translation
|
||||
self._translation: TranslationServiceABC = services.get_service(
|
||||
TranslationServiceABC
|
||||
)
|
||||
self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC)
|
||||
self._t: TranslatePipe = services.get_service(TranslatePipe)
|
||||
# internal stuff
|
||||
self._tasks = services.get_services(TaskABC)
|
||||
|
||||
self._feature_flags: FeatureFlagsSettings = config.get_configuration(
|
||||
FeatureFlagsSettings
|
||||
)
|
||||
self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings)
|
||||
|
||||
# api
|
||||
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
||||
@@ -50,9 +43,7 @@ class Application(DiscordBotApplicationABC):
|
||||
self._is_stopping = False
|
||||
|
||||
async def configure(self):
|
||||
self._translation.load_by_settings(
|
||||
self._configuration.get_configuration(TranslationSettings)
|
||||
)
|
||||
self._translation.load_by_settings(self._configuration.get_configuration(TranslationSettings))
|
||||
|
||||
async def main(self):
|
||||
try:
|
||||
@@ -68,8 +59,9 @@ class Application(DiscordBotApplicationABC):
|
||||
return
|
||||
|
||||
self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}")
|
||||
for task in self._tasks:
|
||||
await self._bot.add_cog(task)
|
||||
if not self._config.get_configuration(MAINTENANCE):
|
||||
for task in self._tasks:
|
||||
await self._bot.add_cog(task)
|
||||
|
||||
await self._bot.start_async()
|
||||
await self._bot.stop_async()
|
||||
@@ -95,8 +87,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
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"Version": {
|
||||
"Major": "1",
|
||||
"Minor": "2",
|
||||
"Micro": "0"
|
||||
"Micro": "1"
|
||||
},
|
||||
"Author": "Sven Heidemann",
|
||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||
@@ -31,7 +31,9 @@
|
||||
"icmplib==3.0.4",
|
||||
"ariadne==0.20.1",
|
||||
"cryptography==41.0.4",
|
||||
"discord==2.3.2"
|
||||
"discord==2.3.2",
|
||||
"bs4==0.0.1",
|
||||
"lxml==4.9.3"
|
||||
],
|
||||
"DevDependencies": [
|
||||
"cpl-cli==2023.4.0.post3",
|
||||
|
1
bot/src/bot/config
Submodule
1
bot/src/bot/config
Submodule
Submodule bot/src/bot/config added at c11ca6f2e8
@@ -15,7 +15,7 @@ __title__ = "bot.extension"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -13,6 +13,4 @@ class InitBotExtension(ApplicationExtensionABC):
|
||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||
settings = config.get_configuration(TechnicianConfig)
|
||||
|
||||
bot: DiscordBotServiceABC = services.get_service(
|
||||
DiscordBotServiceABC, max_messages=settings.cache_max_messages
|
||||
)
|
||||
bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC, max_messages=settings.cache_max_messages)
|
||||
|
@@ -9,7 +9,7 @@ from bot.application import Application
|
||||
from bot.extension.init_bot_extension import InitBotExtension
|
||||
from bot.startup import Startup
|
||||
from bot.startup_discord_extension import StartupDiscordExtension
|
||||
from bot.startup_migration_extension import StartupMigrationExtension
|
||||
from bot_data.startup_migration_extension import StartupMigrationExtension
|
||||
from bot.startup_module_extension import StartupModuleExtension
|
||||
from bot.startup_settings_extension import StartupSettingsExtension
|
||||
from bot_api.app_api_extension import AppApiExtension
|
||||
|
@@ -50,9 +50,7 @@ class Startup(StartupABC):
|
||||
services.add_singleton(CustomFileLoggerABC, ApiLogger)
|
||||
|
||||
services.add_translation()
|
||||
services.add_db_context(
|
||||
DBContext, self._config.get_configuration(DatabaseSettings)
|
||||
)
|
||||
services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings))
|
||||
|
||||
provider = services.build_service_provider()
|
||||
# instantiate custom logger
|
||||
|
@@ -9,13 +9,9 @@ class StartupDiscordExtension(StartupExtensionABC):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def configure_configuration(
|
||||
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(
|
||||
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_discord()
|
||||
dcc = get_discord_collection(services)
|
||||
|
@@ -18,15 +18,11 @@ class StartupModuleExtension(StartupExtensionABC):
|
||||
|
||||
self._modules = ModuleList.get_modules()
|
||||
|
||||
def configure_configuration(
|
||||
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
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
|
||||
):
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
provider = services.build_service_provider()
|
||||
dc_collection: DiscordCollectionABC = provider.get_service(DiscordCollectionABC)
|
||||
|
||||
|
@@ -8,44 +8,39 @@ 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.environment_variables import MAINTENANCE, MIGRATION_ONLY
|
||||
|
||||
|
||||
class StartupSettingsExtension(StartupExtensionABC):
|
||||
def __init__(self):
|
||||
self._start_time = datetime.now()
|
||||
|
||||
def configure_configuration(
|
||||
self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC
|
||||
):
|
||||
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("SDB_")
|
||||
configuration.add_environment_variables("DISCORD_")
|
||||
configuration.add_configuration(
|
||||
MAINTENANCE, configuration.get_configuration(MAINTENANCE) in [True, "true", "True"]
|
||||
)
|
||||
configuration.add_configuration(
|
||||
MIGRATION_ONLY, configuration.get_configuration(MIGRATION_ONLY) in [True, "true", "True"]
|
||||
)
|
||||
|
||||
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_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_json_file(
|
||||
f"config/feature-flags.{environment.environment_name}.json", optional=True
|
||||
)
|
||||
configuration.add_json_file(
|
||||
f"config/feature-flags.{environment.host_name}.json", optional=True
|
||||
)
|
||||
configuration.add_json_file(f"config/feature-flags.{environment.environment_name}.json", optional=True)
|
||||
configuration.add_json_file(f"config/feature-flags.{environment.host_name}.json", optional=True)
|
||||
|
||||
configuration.add_configuration("Startup_StartTime", str(self._start_time))
|
||||
self._configure_settings_with_sub_settings(
|
||||
configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key
|
||||
)
|
||||
|
||||
def configure_services(
|
||||
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@@ -57,6 +52,4 @@ class StartupSettingsExtension(StartupExtensionABC):
|
||||
return
|
||||
|
||||
for sub_settings in list_atr(settings):
|
||||
config.add_configuration(
|
||||
f"{type(sub_settings).__name__}_{atr(sub_settings)}", sub_settings
|
||||
)
|
||||
config.add_configuration(f"{type(sub_settings).__name__}_{atr(sub_settings)}", sub_settings)
|
||||
|
@@ -90,7 +90,8 @@
|
||||
"booting": "Ich fahre gerade hoch...",
|
||||
"restart": "Muss neue Kekse holen...",
|
||||
"running": "Ich esse Kekse :D",
|
||||
"shutdown": "Ich werde bestimmt wieder kommen..."
|
||||
"shutdown": "Ich werde bestimmt wieder kommen...",
|
||||
"maintenance": "In Wartung!"
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.abc"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -40,15 +40,11 @@ class AuthServiceABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_filtered_auth_users_async(
|
||||
self, criteria: AuthUserSelectCriteria
|
||||
) -> AuthUserFilteredResultDTO:
|
||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_auth_user_by_email_async(
|
||||
self, email: str, with_password: bool = False
|
||||
) -> AuthUserDTO:
|
||||
async def get_auth_user_by_email_async(self, email: str, with_password: bool = False) -> AuthUserDTO:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -3,9 +3,7 @@ from abc import ABC, abstractmethod
|
||||
|
||||
class SelectCriteriaABC(ABC):
|
||||
@abstractmethod
|
||||
def __init__(
|
||||
self, page_index: int, page_size: int, sort_direction: str, sort_column: str
|
||||
):
|
||||
def __init__(self, page_index: int, page_size: int, sort_direction: str, sort_column: str):
|
||||
self.page_index = page_index
|
||||
self.page_size = page_size
|
||||
self.sort_direction = sort_direction
|
||||
|
@@ -57,9 +57,7 @@ class Api(Flask):
|
||||
# Added async_mode see link below
|
||||
# https://github.com/miguelgrinberg/Flask-SocketIO/discussions/1849
|
||||
# https://stackoverflow.com/questions/39370848/flask-socket-io-sometimes-client-calls-freeze-the-server
|
||||
self._socketio = SocketIO(
|
||||
self, cors_allowed_origins="*", path="/api/socket.io", async_mode="eventlet"
|
||||
)
|
||||
self._socketio = SocketIO(self, cors_allowed_origins="*", path="/api/socket.io", async_mode="eventlet")
|
||||
self._socketio.on_event("connect", self.on_connect)
|
||||
self._socketio.on_event("disconnect", self.on_disconnect)
|
||||
|
||||
@@ -145,9 +143,7 @@ class Api(Flask):
|
||||
data = request.get_data()
|
||||
data = "" if len(data) == 0 else str(data.decode(encoding="utf-8"))
|
||||
|
||||
text = textwrap.dedent(
|
||||
f"Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tResponse: {data}"
|
||||
)
|
||||
text = textwrap.dedent(f"Request: {request_id}:\n\tHeader:\n\t\t{headers}\n\tResponse: {data}")
|
||||
self._logger.trace(__name__, text)
|
||||
|
||||
return response
|
||||
@@ -162,9 +158,7 @@ class Api(Flask):
|
||||
# from waitress import serve
|
||||
# https://docs.pylonsproject.org/projects/waitress/en/stable/arguments.html
|
||||
# serve(self, host=self._apt_settings.host, port=self._apt_settings.port, threads=10, connection_limit=1000, channel_timeout=10)
|
||||
self._socket = eventlet.listen(
|
||||
(self._api_settings.host, self._api_settings.port)
|
||||
)
|
||||
self._socket = eventlet.listen((self._api_settings.host, self._api_settings.port))
|
||||
wsgi.server(self._socket, self, log_output=False)
|
||||
|
||||
def stop(self):
|
||||
|
@@ -26,21 +26,15 @@ class ApiModule(ModuleABC):
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.api_module)
|
||||
|
||||
def configure_configuration(
|
||||
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
cwd = env.working_directory
|
||||
env.set_working_directory(os.path.dirname(os.path.realpath(__file__)))
|
||||
config.add_json_file(f"config/apisettings.json", optional=False)
|
||||
config.add_json_file(
|
||||
f"config/apisettings.{env.environment_name}.json", optional=True
|
||||
)
|
||||
config.add_json_file(f"config/apisettings.{env.environment_name}.json", optional=True)
|
||||
config.add_json_file(f"config/apisettings.{env.host_name}.json", optional=True)
|
||||
env.set_working_directory(cwd)
|
||||
|
||||
def configure_services(
|
||||
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_singleton(EMailClientABC, EMailClient)
|
||||
|
||||
services.add_singleton(ApiThread)
|
||||
|
@@ -12,9 +12,7 @@ class AppApiExtension(ApplicationExtensionABC):
|
||||
ApplicationExtensionABC.__init__(self)
|
||||
|
||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||
feature_flags: FeatureFlagsSettings = config.get_configuration(
|
||||
FeatureFlagsSettings
|
||||
)
|
||||
feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings)
|
||||
if not feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
||||
return
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"Version": {
|
||||
"Major": "1",
|
||||
"Minor": "2",
|
||||
"Micro": "0"
|
||||
"Micro": "1"
|
||||
},
|
||||
"Author": "",
|
||||
"AuthorEmail": "",
|
||||
|
1
bot/src/bot_api/config
Submodule
1
bot/src/bot_api/config
Submodule
Submodule bot/src/bot_api/config added at 521951b8ab
@@ -15,7 +15,7 @@ __title__ = "bot_api.configuration"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -16,9 +16,7 @@ class AuthenticationSettings(ConfigurationModelABC):
|
||||
self._issuer = "" if issuer is None else issuer
|
||||
self._audience = "" if audience is None else audience
|
||||
self._token_expire_time = 0 if token_expire_time is None else token_expire_time
|
||||
self._refresh_token_expire_time = (
|
||||
0 if refresh_token_expire_time is None else refresh_token_expire_time
|
||||
)
|
||||
self._refresh_token_expire_time = 0 if refresh_token_expire_time is None else refresh_token_expire_time
|
||||
|
||||
@property
|
||||
def secret_key(self) -> str:
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.controller"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -70,9 +70,7 @@ class AuthController:
|
||||
|
||||
@Route.post(f"{BasePath}/register")
|
||||
async def register(self):
|
||||
dto: AuthUserDTO = JSONProcessor.process(
|
||||
AuthUserDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||
self._auth_service.add_auth_user(dto)
|
||||
return "", 200
|
||||
|
||||
@@ -83,9 +81,7 @@ class AuthController:
|
||||
|
||||
@Route.post(f"{BasePath}/login")
|
||||
async def login(self) -> Response:
|
||||
dto: AuthUserDTO = JSONProcessor.process(
|
||||
AuthUserDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||
result = await self._auth_service.login_async(dto)
|
||||
return jsonify(result.to_dict())
|
||||
|
||||
@@ -114,52 +110,40 @@ class AuthController:
|
||||
|
||||
@Route.post(f"{BasePath}/reset-password")
|
||||
async def reset_password(self):
|
||||
dto: ResetPasswordDTO = JSONProcessor.process(
|
||||
ResetPasswordDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.reset_password_async(dto)
|
||||
return "", 200
|
||||
|
||||
@Route.post(f"{BasePath}/update-user")
|
||||
@Route.authorize
|
||||
async def update_user(self):
|
||||
dto: UpdateAuthUserDTO = JSONProcessor.process(
|
||||
UpdateAuthUserDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.update_user_async(dto)
|
||||
return "", 200
|
||||
|
||||
@Route.post(f"{BasePath}/update-user-as-admin")
|
||||
@Route.authorize(role=AuthRoleEnum.admin)
|
||||
async def update_user_as_admin(self):
|
||||
dto: UpdateAuthUserDTO = JSONProcessor.process(
|
||||
UpdateAuthUserDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: UpdateAuthUserDTO = JSONProcessor.process(UpdateAuthUserDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.update_user_as_admin_async(dto)
|
||||
return "", 200
|
||||
|
||||
@Route.post(f"{BasePath}/refresh")
|
||||
async def refresh(self) -> Response:
|
||||
dto: TokenDTO = JSONProcessor.process(
|
||||
TokenDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True))
|
||||
result = await self._auth_service.refresh_async(dto)
|
||||
return jsonify(result.to_dict())
|
||||
|
||||
@Route.post(f"{BasePath}/revoke")
|
||||
async def revoke(self):
|
||||
dto: TokenDTO = JSONProcessor.process(
|
||||
TokenDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: TokenDTO = JSONProcessor.process(TokenDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.revoke_async(dto)
|
||||
return "", 200
|
||||
|
||||
@Route.post(f"{BasePath}/delete-user")
|
||||
@Route.authorize(role=AuthRoleEnum.admin)
|
||||
async def delete_user(self):
|
||||
dto: AuthUserDTO = JSONProcessor.process(
|
||||
AuthUserDTO, request.get_json(force=True, silent=True)
|
||||
)
|
||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
||||
await self._auth_service.delete_auth_user_async(dto)
|
||||
return "", 200
|
||||
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.event"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.exception"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.filter"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -13,9 +13,7 @@ class AuthUserSelectCriteria(SelectCriteriaABC):
|
||||
email: str,
|
||||
auth_role: int,
|
||||
):
|
||||
SelectCriteriaABC.__init__(
|
||||
self, page_index, page_size, sort_direction, sort_column
|
||||
)
|
||||
SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column)
|
||||
|
||||
self.first_name = first_name
|
||||
self.last_name = last_name
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.filter.discord"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -10,8 +10,6 @@ class ServerSelectCriteria(SelectCriteriaABC):
|
||||
sort_column: str,
|
||||
name: str,
|
||||
):
|
||||
SelectCriteriaABC.__init__(
|
||||
self, page_index, page_size, sort_direction, sort_column
|
||||
)
|
||||
SelectCriteriaABC.__init__(self, page_index, page_size, sort_direction, sort_column)
|
||||
|
||||
self.name = name
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.logging"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.model"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.model.discord"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -11,9 +11,7 @@ class ErrorDTO(DtoABC):
|
||||
def __init__(self, error_code: Optional[ServiceErrorCode], message: str):
|
||||
DtoABC.__init__(self)
|
||||
|
||||
self._error_code = (
|
||||
ServiceErrorCode.Unknown if error_code is None else error_code
|
||||
)
|
||||
self._error_code = ServiceErrorCode.Unknown if error_code is None else error_code
|
||||
self._message = message
|
||||
|
||||
@property
|
||||
|
@@ -34,9 +34,7 @@ class UpdateAuthUserDTO(DtoABC):
|
||||
def from_dict(self, values: dict):
|
||||
self._auth_user = AuthUserDTO().from_dict(values["authUser"])
|
||||
self._new_auth_user = AuthUserDTO().from_dict(values["newAuthUser"])
|
||||
self._change_password = (
|
||||
False if "changePassword" not in values else bool(values["changePassword"])
|
||||
)
|
||||
self._change_password = False if "changePassword" not in values else bool(values["changePassword"])
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.route"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -65,9 +65,7 @@ class Route:
|
||||
by_api_key=False,
|
||||
):
|
||||
if f is None:
|
||||
return functools.partial(
|
||||
cls.authorize, role=role, skip_in_dev=skip_in_dev, by_api_key=by_api_key
|
||||
)
|
||||
return functools.partial(cls.authorize, role=role, skip_in_dev=skip_in_dev, by_api_key=by_api_key)
|
||||
|
||||
@wraps(f)
|
||||
async def decorator(*args, **kwargs):
|
||||
@@ -78,9 +76,7 @@ class Route:
|
||||
api_key = None
|
||||
if "Authorization" in request.headers:
|
||||
if " " not in request.headers.get("Authorization"):
|
||||
ex = ServiceException(
|
||||
ServiceErrorCode.Unauthorized, f"Token not set"
|
||||
)
|
||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token not set")
|
||||
error = ErrorDTO(ex.error_code, ex.message)
|
||||
return jsonify(error.to_dict()), 401
|
||||
|
||||
@@ -102,9 +98,7 @@ class Route:
|
||||
return jsonify(e), 500
|
||||
|
||||
if not valid:
|
||||
ex = ServiceException(
|
||||
ServiceErrorCode.Unauthorized, f"API-Key invalid"
|
||||
)
|
||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"API-Key invalid")
|
||||
error = ErrorDTO(ex.error_code, ex.message)
|
||||
return jsonify(error.to_dict()), 401
|
||||
|
||||
@@ -116,9 +110,7 @@ class Route:
|
||||
return jsonify(error.to_dict()), 401
|
||||
|
||||
if cls._auth_users is None or cls._auth is None:
|
||||
ex = ServiceException(
|
||||
ServiceErrorCode.Unauthorized, f"Authorize is not initialized"
|
||||
)
|
||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Authorize is not initialized")
|
||||
error = ErrorDTO(ex.error_code, ex.message)
|
||||
return jsonify(error.to_dict()), 401
|
||||
|
||||
@@ -140,9 +132,7 @@ class Route:
|
||||
return jsonify(error.to_dict()), 401
|
||||
|
||||
if role is not None and user.auth_role.value < role.value:
|
||||
ex = ServiceException(
|
||||
ServiceErrorCode.Unauthorized, f"Role {role} required"
|
||||
)
|
||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Role {role} required")
|
||||
error = ErrorDTO(ex.error_code, ex.message)
|
||||
return jsonify(error.to_dict()), 403
|
||||
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.service"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -90,9 +90,7 @@ class AuthService(AuthServiceABC):
|
||||
|
||||
def _get_api_key_str(self, api_key: ApiKey) -> str:
|
||||
return hashlib.sha256(
|
||||
f"{api_key.identifier}:{api_key.key}+{self._auth_settings.secret_key}".encode(
|
||||
"utf-8"
|
||||
)
|
||||
f"{api_key.identifier}:{api_key.key}+{self._auth_settings.secret_key}".encode("utf-8")
|
||||
).hexdigest()
|
||||
|
||||
def generate_token(self, user: AuthUser) -> str:
|
||||
@@ -101,8 +99,7 @@ class AuthService(AuthServiceABC):
|
||||
"user_id": user.id,
|
||||
"email": user.email,
|
||||
"role": user.auth_role.value,
|
||||
"exp": datetime.now(tz=timezone.utc)
|
||||
+ timedelta(days=self._auth_settings.token_expire_time),
|
||||
"exp": datetime.now(tz=timezone.utc) + timedelta(days=self._auth_settings.token_expire_time),
|
||||
"iss": self._auth_settings.issuer,
|
||||
"aud": self._auth_settings.audience,
|
||||
},
|
||||
@@ -158,9 +155,7 @@ class AuthService(AuthServiceABC):
|
||||
def _create_and_save_refresh_token(self, user: AuthUser) -> str:
|
||||
token = str(uuid.uuid4())
|
||||
user.refresh_token = token
|
||||
user.refresh_token_expire_time = datetime.now() + timedelta(
|
||||
days=self._auth_settings.refresh_token_expire_time
|
||||
)
|
||||
user.refresh_token_expire_time = datetime.now() + timedelta(days=self._auth_settings.refresh_token_expire_time)
|
||||
self._auth_users.update_auth_user(user)
|
||||
self._db.save_changes()
|
||||
return token
|
||||
@@ -193,12 +188,8 @@ class AuthService(AuthServiceABC):
|
||||
|
||||
self._send_link_mail(
|
||||
user.email,
|
||||
self._t.transform("api.auth.confirmation.subject").format(
|
||||
user.first_name, user.last_name
|
||||
),
|
||||
self._t.transform("api.auth.confirmation.message").format(
|
||||
url, user.confirmation_id
|
||||
),
|
||||
self._t.transform("api.auth.confirmation.subject").format(user.first_name, user.last_name),
|
||||
self._t.transform("api.auth.confirmation.message").format(url, user.confirmation_id),
|
||||
)
|
||||
|
||||
def _send_forgot_password_id_to_user(self, user: AuthUser):
|
||||
@@ -208,38 +199,28 @@ class AuthService(AuthServiceABC):
|
||||
|
||||
self._send_link_mail(
|
||||
user.email,
|
||||
self._t.transform("api.auth.forgot_password.subject").format(
|
||||
user.first_name, user.last_name
|
||||
),
|
||||
self._t.transform("api.auth.forgot_password.message").format(
|
||||
url, user.forgot_password_id
|
||||
),
|
||||
self._t.transform("api.auth.forgot_password.subject").format(user.first_name, user.last_name),
|
||||
self._t.transform("api.auth.forgot_password.message").format(url, user.forgot_password_id),
|
||||
)
|
||||
|
||||
async def get_all_auth_users_async(self) -> List[AuthUserDTO]:
|
||||
result = self._auth_users.get_all_auth_users().select(lambda x: AUT.to_dto(x))
|
||||
return List(AuthUserDTO, result)
|
||||
|
||||
async def get_filtered_auth_users_async(
|
||||
self, criteria: AuthUserSelectCriteria
|
||||
) -> AuthUserFilteredResultDTO:
|
||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO:
|
||||
users = self._auth_users.get_filtered_auth_users(criteria)
|
||||
result = users.result.select(lambda x: AUT.to_dto(x))
|
||||
|
||||
return AuthUserFilteredResultDTO(List(AuthUserDTO, result), users.total_count)
|
||||
|
||||
async def get_auth_user_by_email_async(
|
||||
self, email: str, with_password: bool = False
|
||||
) -> AuthUserDTO:
|
||||
async def get_auth_user_by_email_async(self, email: str, with_password: bool = False) -> AuthUserDTO:
|
||||
try:
|
||||
# todo: check if logged in user is admin then send mail
|
||||
user = self._auth_users.get_auth_user_by_email(email)
|
||||
return AUT.to_dto(user, password=user.password if with_password else None)
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, f"AuthUser not found", e)
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.InvalidData, f"User not found {email}"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"User not found {email}")
|
||||
|
||||
async def find_auth_user_by_email_async(self, email: str) -> Optional[AuthUser]:
|
||||
user = self._auth_users.find_auth_user_by_email(email)
|
||||
@@ -257,22 +238,16 @@ class AuthService(AuthServiceABC):
|
||||
user.password_salt = uuid.uuid4()
|
||||
user.password = self._hash_sha256(user_dto.password, user.password_salt)
|
||||
if not self._is_email_valid(user.email):
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.InvalidData, "Invalid E-Mail address"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, "Invalid E-Mail address")
|
||||
|
||||
try:
|
||||
user.confirmation_id = uuid.uuid4()
|
||||
self._auth_users.add_auth_user(user)
|
||||
self._send_confirmation_id_to_user(user)
|
||||
self._db.save_changes()
|
||||
self._logger.info(
|
||||
__name__, f"Added auth user with E-Mail: {user_dto.email}"
|
||||
)
|
||||
self._logger.info(__name__, f"Added auth user with E-Mail: {user_dto.email}")
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__, f"Cannot add user with E-Mail {user_dto.email}", e
|
||||
)
|
||||
self._logger.error(__name__, f"Cannot add user with E-Mail {user_dto.email}", e)
|
||||
raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail")
|
||||
|
||||
async def add_auth_user_by_oauth_async(self, dto: OAuthDTO):
|
||||
@@ -288,20 +263,14 @@ class AuthService(AuthServiceABC):
|
||||
db_user.first_name = dto.user.first_name
|
||||
db_user.last_name = dto.user.last_name
|
||||
db_user.password_salt = uuid.uuid4()
|
||||
db_user.password = self._hash_sha256(
|
||||
dto.user.password, db_user.password_salt
|
||||
)
|
||||
db_user.password = self._hash_sha256(dto.user.password, db_user.password_salt)
|
||||
db_user.oauth_id = None
|
||||
db_user.confirmation_id = uuid.uuid4()
|
||||
self._send_confirmation_id_to_user(db_user)
|
||||
self._auth_users.update_auth_user(db_user)
|
||||
self._logger.info(
|
||||
__name__, f"Added auth user with E-Mail: {dto.user.email}"
|
||||
)
|
||||
self._logger.info(__name__, f"Added auth user with E-Mail: {dto.user.email}")
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__, f"Cannot add user with E-Mail {dto.user.email}", e
|
||||
)
|
||||
self._logger.error(__name__, f"Cannot add user with E-Mail {dto.user.email}", e)
|
||||
raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail")
|
||||
|
||||
self._db.save_changes()
|
||||
@@ -311,16 +280,14 @@ class AuthService(AuthServiceABC):
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty")
|
||||
|
||||
if update_user_dto.auth_user is None:
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.InvalidData, f"Existing user is empty"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"Existing user is empty")
|
||||
|
||||
if update_user_dto.new_auth_user is None:
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty")
|
||||
|
||||
if not self._is_email_valid(
|
||||
update_user_dto.auth_user.email
|
||||
) or not self._is_email_valid(update_user_dto.new_auth_user.email):
|
||||
if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid(
|
||||
update_user_dto.new_auth_user.email
|
||||
):
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail")
|
||||
|
||||
user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email)
|
||||
@@ -333,8 +300,7 @@ class AuthService(AuthServiceABC):
|
||||
# update first name
|
||||
if (
|
||||
update_user_dto.new_auth_user.first_name is not None
|
||||
and update_user_dto.auth_user.first_name
|
||||
!= update_user_dto.new_auth_user.first_name
|
||||
and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name
|
||||
):
|
||||
user.first_name = update_user_dto.new_auth_user.first_name
|
||||
|
||||
@@ -342,8 +308,7 @@ class AuthService(AuthServiceABC):
|
||||
if (
|
||||
update_user_dto.new_auth_user.last_name is not None
|
||||
and update_user_dto.new_auth_user.last_name != ""
|
||||
and update_user_dto.auth_user.last_name
|
||||
!= update_user_dto.new_auth_user.last_name
|
||||
and update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name
|
||||
):
|
||||
user.last_name = update_user_dto.new_auth_user.last_name
|
||||
|
||||
@@ -353,33 +318,22 @@ class AuthService(AuthServiceABC):
|
||||
and update_user_dto.new_auth_user.email != ""
|
||||
and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email
|
||||
):
|
||||
user_by_new_e_mail = self._auth_users.find_auth_user_by_email(
|
||||
update_user_dto.new_auth_user.email
|
||||
)
|
||||
user_by_new_e_mail = self._auth_users.find_auth_user_by_email(update_user_dto.new_auth_user.email)
|
||||
if user_by_new_e_mail is not None:
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.InvalidUser, "User already exists"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists")
|
||||
user.email = update_user_dto.new_auth_user.email
|
||||
|
||||
update_user_dto.auth_user.password = self._hash_sha256(
|
||||
update_user_dto.auth_user.password, user.password_salt
|
||||
)
|
||||
update_user_dto.auth_user.password = self._hash_sha256(update_user_dto.auth_user.password, user.password_salt)
|
||||
if update_user_dto.auth_user.password != user.password:
|
||||
raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong password")
|
||||
|
||||
# update password
|
||||
if (
|
||||
update_user_dto.new_auth_user.password is not None
|
||||
and self._hash_sha256(
|
||||
update_user_dto.new_auth_user.password, user.password_salt
|
||||
)
|
||||
!= user.password
|
||||
and self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt) != user.password
|
||||
):
|
||||
user.password_salt = uuid.uuid4()
|
||||
user.password = self._hash_sha256(
|
||||
update_user_dto.new_auth_user.password, user.password_salt
|
||||
)
|
||||
user.password = self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt)
|
||||
|
||||
self._auth_users.update_auth_user(user)
|
||||
self._db.save_changes()
|
||||
@@ -389,31 +343,23 @@ class AuthService(AuthServiceABC):
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty")
|
||||
|
||||
if update_user_dto.auth_user is None:
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.InvalidData, f"Existing user is empty"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"Existing user is empty")
|
||||
|
||||
if update_user_dto.new_auth_user is None:
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty")
|
||||
|
||||
if not self._is_email_valid(
|
||||
update_user_dto.auth_user.email
|
||||
) or not self._is_email_valid(update_user_dto.new_auth_user.email):
|
||||
if not self._is_email_valid(update_user_dto.auth_user.email) or not self._is_email_valid(
|
||||
update_user_dto.new_auth_user.email
|
||||
):
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail")
|
||||
|
||||
user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email)
|
||||
if user is None:
|
||||
raise ServiceException(ServiceErrorCode.InvalidUser, "User not found")
|
||||
|
||||
if (
|
||||
user.confirmation_id is not None
|
||||
and update_user_dto.new_auth_user.is_confirmed
|
||||
):
|
||||
if user.confirmation_id is not None and update_user_dto.new_auth_user.is_confirmed:
|
||||
user.confirmation_id = None
|
||||
elif (
|
||||
user.confirmation_id is None
|
||||
and not update_user_dto.new_auth_user.is_confirmed
|
||||
):
|
||||
elif user.confirmation_id is None and not update_user_dto.new_auth_user.is_confirmed:
|
||||
user.confirmation_id = uuid.uuid4()
|
||||
# else
|
||||
# raise ServiceException(ServiceErrorCode.InvalidUser, 'E-Mail not confirmed')
|
||||
@@ -421,8 +367,7 @@ class AuthService(AuthServiceABC):
|
||||
# update first name
|
||||
if (
|
||||
update_user_dto.new_auth_user.first_name is not None
|
||||
and update_user_dto.auth_user.first_name
|
||||
!= update_user_dto.new_auth_user.first_name
|
||||
and update_user_dto.auth_user.first_name != update_user_dto.new_auth_user.first_name
|
||||
):
|
||||
user.first_name = update_user_dto.new_auth_user.first_name
|
||||
|
||||
@@ -430,8 +375,7 @@ class AuthService(AuthServiceABC):
|
||||
if (
|
||||
update_user_dto.new_auth_user.last_name is not None
|
||||
and update_user_dto.new_auth_user.last_name != ""
|
||||
and update_user_dto.auth_user.last_name
|
||||
!= update_user_dto.new_auth_user.last_name
|
||||
and update_user_dto.auth_user.last_name != update_user_dto.new_auth_user.last_name
|
||||
):
|
||||
user.last_name = update_user_dto.new_auth_user.last_name
|
||||
|
||||
@@ -441,28 +385,19 @@ class AuthService(AuthServiceABC):
|
||||
and update_user_dto.new_auth_user.email != ""
|
||||
and update_user_dto.auth_user.email != update_user_dto.new_auth_user.email
|
||||
):
|
||||
user_by_new_e_mail = self._auth_users.find_auth_user_by_email(
|
||||
update_user_dto.new_auth_user.email
|
||||
)
|
||||
user_by_new_e_mail = self._auth_users.find_auth_user_by_email(update_user_dto.new_auth_user.email)
|
||||
if user_by_new_e_mail is not None:
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.InvalidUser, "User already exists"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.InvalidUser, "User already exists")
|
||||
user.email = update_user_dto.new_auth_user.email
|
||||
|
||||
# update password
|
||||
if (
|
||||
update_user_dto.new_auth_user.password is not None
|
||||
and update_user_dto.change_password
|
||||
and user.password
|
||||
!= self._hash_sha256(
|
||||
update_user_dto.new_auth_user.password, user.password_salt
|
||||
)
|
||||
and user.password != self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt)
|
||||
):
|
||||
user.password_salt = uuid.uuid4()
|
||||
user.password = self._hash_sha256(
|
||||
update_user_dto.new_auth_user.password, user.password_salt
|
||||
)
|
||||
user.password = self._hash_sha256(update_user_dto.new_auth_user.password, user.password_salt)
|
||||
|
||||
# update role
|
||||
if (
|
||||
@@ -481,9 +416,7 @@ class AuthService(AuthServiceABC):
|
||||
self._db.save_changes()
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, f"Cannot delete user", e)
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.UnableToDelete, f"Cannot delete user by mail {email}"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.UnableToDelete, f"Cannot delete user by mail {email}")
|
||||
|
||||
async def delete_auth_user_async(self, user_dto: AuthUser):
|
||||
try:
|
||||
@@ -567,9 +500,7 @@ class AuthService(AuthServiceABC):
|
||||
if user.id in user_ids:
|
||||
continue
|
||||
|
||||
self._auth_users.add_auth_user_user_rel(
|
||||
AuthUserUsersRelation(db_user, user)
|
||||
)
|
||||
self._auth_users.add_auth_user_user_rel(AuthUserUsersRelation(db_user, user))
|
||||
|
||||
if db_user.confirmation_id is not None and not added_user:
|
||||
raise ServiceException(ServiceErrorCode.Forbidden, "E-Mail not verified")
|
||||
@@ -599,19 +530,13 @@ class AuthService(AuthServiceABC):
|
||||
):
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, "Token expired")
|
||||
|
||||
return TokenDTO(
|
||||
self.generate_token(user), self._create_and_save_refresh_token(user)
|
||||
)
|
||||
return TokenDTO(self.generate_token(user), self._create_and_save_refresh_token(user))
|
||||
except Exception as e:
|
||||
self._logger.error(__name__, f"Refreshing token failed", e)
|
||||
return TokenDTO("", "")
|
||||
|
||||
async def revoke_async(self, token_dto: TokenDTO):
|
||||
if (
|
||||
token_dto is None
|
||||
or token_dto.token is None
|
||||
or token_dto.refresh_token is None
|
||||
):
|
||||
if token_dto is None or token_dto.token is None or token_dto.refresh_token is None:
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, "Token not set")
|
||||
|
||||
try:
|
||||
@@ -664,9 +589,7 @@ class AuthService(AuthServiceABC):
|
||||
)
|
||||
|
||||
if user.confirmation_id is not None:
|
||||
raise ServiceException(
|
||||
ServiceErrorCode.InvalidUser, f"E-Mail not confirmed"
|
||||
)
|
||||
raise ServiceException(ServiceErrorCode.InvalidUser, f"E-Mail not confirmed")
|
||||
|
||||
if user.password is None or rp_dto.password == "":
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, f"Password not set")
|
||||
|
@@ -53,17 +53,13 @@ class DiscordService:
|
||||
if role != AuthRoleEnum.admin:
|
||||
auth_user = self._auth_users.find_auth_user_by_email(token["email"])
|
||||
if auth_user is not None:
|
||||
user_ids = auth_user.users.select(
|
||||
lambda x: x.server is not None and x.server.id
|
||||
)
|
||||
user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.id)
|
||||
servers = servers.where(lambda x: x.id in user_ids)
|
||||
|
||||
servers = List(ServerDTO, servers)
|
||||
return servers.select(self._to_dto).where(lambda x: x.name != "")
|
||||
|
||||
async def get_filtered_servers_async(
|
||||
self, criteria: ServerSelectCriteria
|
||||
) -> ServerFilteredResultDTO:
|
||||
async def get_filtered_servers_async(self, criteria: ServerSelectCriteria) -> ServerFilteredResultDTO:
|
||||
token = self._auth.get_decoded_token_from_request()
|
||||
if token is None or "email" not in token or "role" not in token:
|
||||
raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid")
|
||||
@@ -74,22 +70,15 @@ class DiscordService:
|
||||
if role != AuthRoleEnum.admin:
|
||||
auth_user = self._auth_users.find_auth_user_by_email(token["email"])
|
||||
if auth_user is not None:
|
||||
user_ids = auth_user.users.select(
|
||||
lambda x: x.server is not None and x.server.id
|
||||
)
|
||||
filtered_result.result = filtered_result.result.where(
|
||||
lambda x: x.id in user_ids
|
||||
)
|
||||
user_ids = auth_user.users.select(lambda x: x.server is not None and x.server.id)
|
||||
filtered_result.result = filtered_result.result.where(lambda x: x.id in user_ids)
|
||||
|
||||
servers: List = filtered_result.result.select(self._to_dto).where(
|
||||
lambda x: x.name != ""
|
||||
)
|
||||
servers: List = filtered_result.result.select(self._to_dto).where(lambda x: x.name != "")
|
||||
result = List(ServerDTO, servers)
|
||||
|
||||
if criteria.name is not None and criteria.name != "":
|
||||
result = result.where(
|
||||
lambda x: criteria.name.lower() in x.name.lower()
|
||||
or x.name.lower() == criteria.name.lower()
|
||||
lambda x: criteria.name.lower() in x.name.lower() or x.name.lower() == criteria.name.lower()
|
||||
)
|
||||
|
||||
return ServerFilteredResultDTO(List(ServerDTO, result), servers.count())
|
||||
@@ -98,7 +87,5 @@ class DiscordService:
|
||||
server = self._servers.get_server_by_id(id)
|
||||
guild = self._bot.get_guild(server.discord_id)
|
||||
|
||||
server_dto = ServerTransformer.to_dto(
|
||||
server, guild.name, guild.member_count, guild.icon
|
||||
)
|
||||
server_dto = ServerTransformer.to_dto(server, guild.name, guild.member_count, guild.icon)
|
||||
return server_dto
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.transformer"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -27,35 +27,27 @@ class AuthUserTransformer(TransformerABC):
|
||||
None,
|
||||
None,
|
||||
datetime.now(),
|
||||
AuthRoleEnum.normal
|
||||
if dto.auth_role is None
|
||||
else AuthRoleEnum(dto.auth_role),
|
||||
AuthRoleEnum.normal if dto.auth_role is None else AuthRoleEnum(dto.auth_role),
|
||||
auth_user_id=0 if dto.id is None else dto.id,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@ServiceProviderABC.inject
|
||||
def _is_technician(
|
||||
user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC
|
||||
):
|
||||
def _is_technician(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC):
|
||||
guild = bot.get_guild(user.server.discord_id)
|
||||
member = guild.get_member(user.discord_id)
|
||||
return permissions.is_member_technician(member)
|
||||
|
||||
@staticmethod
|
||||
@ServiceProviderABC.inject
|
||||
def _is_admin(
|
||||
user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC
|
||||
):
|
||||
def _is_admin(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC):
|
||||
guild = bot.get_guild(user.server.discord_id)
|
||||
member = guild.get_member(user.discord_id)
|
||||
return permissions.is_member_admin(member)
|
||||
|
||||
@staticmethod
|
||||
@ServiceProviderABC.inject
|
||||
def _is_moderator(
|
||||
user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC
|
||||
):
|
||||
def _is_moderator(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC):
|
||||
guild = bot.get_guild(user.server.discord_id)
|
||||
member = guild.get_member(user.discord_id)
|
||||
return permissions.is_member_moderator(member)
|
||||
|
@@ -13,9 +13,7 @@ class ServerTransformer(TransformerABC):
|
||||
return Server(dto.discord_id)
|
||||
|
||||
@staticmethod
|
||||
def to_dto(
|
||||
db: Server, name: str, member_count: int, icon_url: Optional[discord.Asset]
|
||||
) -> ServerDTO:
|
||||
def to_dto(db: Server, name: str, member_count: int, icon_url: Optional[discord.Asset]) -> ServerDTO:
|
||||
return ServerDTO(
|
||||
db.id,
|
||||
db.discord_id,
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.abc"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -45,9 +45,7 @@ class ClientUtilsABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_auto_complete_list(
|
||||
self, _l: List, current: str, select: Callable = None
|
||||
) -> List:
|
||||
def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
@@ -77,3 +75,7 @@ class ClientUtilsABC(ABC):
|
||||
@abstractmethod
|
||||
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def set_maintenance_mode(self, state: bool):
|
||||
pass
|
||||
|
@@ -18,9 +18,7 @@ class CustomFileLoggerABC(Logger, ABC):
|
||||
env: ApplicationEnvironmentABC,
|
||||
):
|
||||
self._key = key
|
||||
self._settings: LoggingSettings = config.get_configuration(
|
||||
f"{FileLoggingSettings.__name__}_{key}"
|
||||
)
|
||||
self._settings: LoggingSettings = config.get_configuration(f"{FileLoggingSettings.__name__}_{key}")
|
||||
Logger.__init__(self, self._settings, time_format, env)
|
||||
self._begin_log()
|
||||
|
||||
@@ -34,9 +32,7 @@ class CustomFileLoggerABC(Logger, ABC):
|
||||
self.info(__name__, f"Starting...")
|
||||
self._console = LoggingLevelEnum(console_level)
|
||||
|
||||
def _get_string(
|
||||
self, name_list_as_str: str, level: LoggingLevelEnum, message: str
|
||||
) -> str:
|
||||
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} ]"
|
||||
|
@@ -13,9 +13,7 @@ class MessageServiceABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def delete_messages(
|
||||
self, messages: List[discord.Message], guild_id: int, without_tracking=False
|
||||
):
|
||||
async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -6,6 +6,7 @@ from cpl_core.dependency_injection import ServiceProviderABC
|
||||
from cpl_discord.service import DiscordBotServiceABC
|
||||
from discord.ext import commands
|
||||
|
||||
from bot_core.environment_variables import MAINTENANCE
|
||||
from bot_core.logging.task_logger import TaskLogger
|
||||
|
||||
|
||||
@@ -15,15 +16,17 @@ class TaskABC(commands.Cog):
|
||||
commands.Cog.__init__(self)
|
||||
|
||||
@ServiceProviderABC.inject
|
||||
async def _wait_until_ready(
|
||||
self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC
|
||||
):
|
||||
def _is_maintenance(self, config: ConfigurationABC) -> bool:
|
||||
return config.get_configuration(MAINTENANCE) is True
|
||||
|
||||
@ServiceProviderABC.inject
|
||||
async def _wait_until_ready(self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC):
|
||||
logger.debug(__name__, f"Waiting before {type(self).__name__}")
|
||||
await bot.wait_until_ready()
|
||||
|
||||
async def wait():
|
||||
is_ready = config.get_configuration("IS_READY")
|
||||
if is_ready != "true":
|
||||
is_ready = config.get_configuration("IS_READY") is True
|
||||
if not is_ready:
|
||||
await asyncio.sleep(1)
|
||||
await wait()
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"Version": {
|
||||
"Major": "1",
|
||||
"Minor": "2",
|
||||
"Micro": "0"
|
||||
"Micro": "1"
|
||||
},
|
||||
"Author": "Sven Heidemann",
|
||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.configuration"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -10,9 +10,7 @@ class FileLoggingSettings(LoggingSettings):
|
||||
console_log_level: LoggingLevelEnum = None,
|
||||
file_log_level: LoggingLevelEnum = None,
|
||||
):
|
||||
LoggingSettings.__init__(
|
||||
self, path, filename, console_log_level, file_log_level
|
||||
)
|
||||
LoggingSettings.__init__(self, path, filename, console_log_level, file_log_level)
|
||||
|
||||
self._key = key
|
||||
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.core_extension"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -17,9 +17,7 @@ class CoreExtension(ApplicationExtensionABC):
|
||||
ApplicationExtensionABC.__init__(self)
|
||||
|
||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||
feature_flags: FeatureFlagsSettings = config.get_configuration(
|
||||
FeatureFlagsSettings
|
||||
)
|
||||
feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings)
|
||||
if not feature_flags.get_flag(FeatureFlagsEnum.core_module):
|
||||
return
|
||||
|
||||
|
@@ -15,14 +15,8 @@ class CoreExtensionModule(ModuleABC):
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_extension_module)
|
||||
|
||||
def configure_configuration(
|
||||
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(
|
||||
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
services.add_transient(
|
||||
DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent
|
||||
)
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_transient(DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent)
|
||||
|
@@ -1,16 +1,19 @@
|
||||
import asyncio
|
||||
|
||||
from cpl_core.configuration import ConfigurationABC
|
||||
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_abc import ClientUtilsABC
|
||||
from bot_core.environment_variables import MAINTENANCE
|
||||
|
||||
|
||||
class CoreExtensionOnReadyEvent(OnReadyABC):
|
||||
def __init__(
|
||||
self,
|
||||
config: ConfigurationABC,
|
||||
logger: LoggerABC,
|
||||
bot: DiscordBotServiceABC,
|
||||
client_utils: ClientUtilsABC,
|
||||
@@ -18,6 +21,7 @@ class CoreExtensionOnReadyEvent(OnReadyABC):
|
||||
):
|
||||
OnReadyABC.__init__(self)
|
||||
|
||||
self._config = config
|
||||
self._logger = logger
|
||||
self._bot = bot
|
||||
self._client_utils = client_utils
|
||||
@@ -27,5 +31,5 @@ class CoreExtensionOnReadyEvent(OnReadyABC):
|
||||
|
||||
async def on_ready(self):
|
||||
self._logger.debug(__name__, f"Module {type(self)} started")
|
||||
await self._client_utils.presence_game("common.presence.running")
|
||||
await self._client_utils.set_maintenance_mode(self._config.get_configuration(MAINTENANCE))
|
||||
self._logger.trace(__name__, f"Module {type(self)} stopped")
|
||||
|
@@ -20,14 +20,10 @@ class CoreModule(ModuleABC):
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_module)
|
||||
|
||||
def configure_configuration(
|
||||
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(
|
||||
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_transient(ConfigService)
|
||||
services.add_transient(MessageServiceABC, MessageService)
|
||||
services.add_transient(ClientUtilsABC, ClientUtilsService)
|
||||
|
2
bot/src/bot_core/environment_variables.py
Normal file
2
bot/src/bot_core/environment_variables.py
Normal file
@@ -0,0 +1,2 @@
|
||||
MIGRATION_ONLY = "MIGRATION_ONLY"
|
||||
MAINTENANCE = "MAINTENANCE"
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.events"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.exception"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.helper"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -44,9 +44,7 @@ class CommandChecks:
|
||||
async def check_is_member_admin(ctx: Context):
|
||||
has_permission = cls._permissions.is_member_admin(ctx.author)
|
||||
if not has_permission:
|
||||
await cls._message_service.send_ctx_msg(
|
||||
ctx, cls._t.transform("common.no_permission_message")
|
||||
)
|
||||
await cls._message_service.send_ctx_msg(ctx, cls._t.transform("common.no_permission_message"))
|
||||
raise CheckError(f"Member {ctx.author.name} is not admin")
|
||||
|
||||
return has_permission
|
||||
@@ -58,9 +56,7 @@ class CommandChecks:
|
||||
async def check_is_member_technician(ctx: Context):
|
||||
has_permission = cls._permissions.is_member_technician(ctx.author)
|
||||
if not has_permission:
|
||||
await cls._message_service.send_ctx_msg(
|
||||
ctx, cls._t.transform("common.no_permission_message")
|
||||
)
|
||||
await cls._message_service.send_ctx_msg(ctx, cls._t.transform("common.no_permission_message"))
|
||||
raise CheckError(f"Member {ctx.author.name} is not technician")
|
||||
|
||||
return has_permission
|
||||
@@ -72,9 +68,7 @@ class CommandChecks:
|
||||
async def check_is_member_moderator(ctx: Context):
|
||||
has_permission = cls._permissions.is_member_moderator(ctx.author)
|
||||
if not has_permission:
|
||||
await cls._message_service.send_ctx_msg(
|
||||
ctx, cls._t.transform("common.no_permission_message")
|
||||
)
|
||||
await cls._message_service.send_ctx_msg(ctx, cls._t.transform("common.no_permission_message"))
|
||||
raise CheckError(f"Member {ctx.author.name} is not moderator")
|
||||
|
||||
return has_permission
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import inspect
|
||||
from typing import Optional
|
||||
|
||||
from discord.ext import commands
|
||||
@@ -17,11 +18,18 @@ class EventChecks:
|
||||
cls._client_utils = client_utils
|
||||
|
||||
@classmethod
|
||||
def check_is_ready(cls):
|
||||
async def check_if_bot_is_ready() -> bool:
|
||||
def check_is_ready(cls, func):
|
||||
async def check_if_bot_is_ready(*args, **kwargs):
|
||||
result = await cls._client_utils.check_if_bot_is_ready_yet()
|
||||
if not result:
|
||||
raise CheckError(f"Bot is not ready")
|
||||
return result
|
||||
|
||||
return commands.check(check_if_bot_is_ready)
|
||||
def empty(*args, **kwargs):
|
||||
return
|
||||
|
||||
return empty
|
||||
return await func(*args, **kwargs)
|
||||
|
||||
check_if_bot_is_ready.__name__ = func.__name__
|
||||
sig = inspect.signature(func)
|
||||
check_if_bot_is_ready.__signature__ = sig.replace(parameters=tuple(sig.parameters.values())[1:])
|
||||
return check_if_bot_is_ready
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.logging"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.pipes"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.service"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports:
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -16,6 +16,7 @@ from bot_core.abc.client_utils_abc import ClientUtilsABC
|
||||
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_core.environment_variables import MAINTENANCE
|
||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||
from bot_data.abc.user_joined_voice_channel_repository_abc import (
|
||||
@@ -62,40 +63,39 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
|
||||
def received_command(self, guild_id: int):
|
||||
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.id
|
||||
)
|
||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
||||
client.received_command_count += 1
|
||||
self._clients.update_client(client)
|
||||
self._db.save_changes()
|
||||
|
||||
def moved_user(self, guild_id: int):
|
||||
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.id
|
||||
)
|
||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
||||
client.moved_users_count += 1
|
||||
self._clients.update_client(client)
|
||||
self._db.save_changes()
|
||||
|
||||
def moved_users(self, guild_id: int, count: int):
|
||||
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.id
|
||||
)
|
||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
||||
client.moved_users_count += count
|
||||
self._clients.update_client(client)
|
||||
self._db.save_changes()
|
||||
|
||||
def get_client(self, dc_ic: int, guild_id: int):
|
||||
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.id
|
||||
)
|
||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
||||
return client
|
||||
|
||||
async def check_if_bot_is_ready_yet(self) -> bool:
|
||||
if self._config.get_configuration("IS_READY") == "true":
|
||||
if self._config.get_configuration(MAINTENANCE):
|
||||
self._logger.warn(
|
||||
__name__,
|
||||
f"Bot is in maintenance mode",
|
||||
)
|
||||
return False
|
||||
|
||||
if self._config.get_configuration("IS_READY") is True:
|
||||
return True
|
||||
|
||||
self._logger.debug(
|
||||
@@ -129,9 +129,7 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
await self._bot.change_presence(activity=discord.Game(name=name))
|
||||
self._logger.info(__name__, f"Set presence {name}")
|
||||
|
||||
def get_auto_complete_list(
|
||||
self, _l: List, current: str, select: Callable = None
|
||||
) -> List:
|
||||
def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List:
|
||||
if current != "":
|
||||
if select is None:
|
||||
select = lambda x: x
|
||||
@@ -154,9 +152,7 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
) -> bool:
|
||||
umcph = None
|
||||
try:
|
||||
umcph = self._umcphs.find_user_message_count_per_hour_by_user_id_and_date(
|
||||
user.id, created_at
|
||||
)
|
||||
umcph = self._umcphs.find_user_message_count_per_hour_by_user_id_and_date(user.id, created_at)
|
||||
if umcph is None:
|
||||
self._umcphs.add_user_message_count_per_hour(
|
||||
UserMessageCountPerHour(
|
||||
@@ -169,11 +165,7 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
|
||||
self._db.save_changes()
|
||||
|
||||
umcph = (
|
||||
self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(
|
||||
user.id, created_at
|
||||
)
|
||||
)
|
||||
umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.id, created_at)
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__,
|
||||
@@ -205,9 +197,7 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
|
||||
def get_ontime_for_user(self, user: User) -> float:
|
||||
return round(
|
||||
self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(
|
||||
user.id
|
||||
)
|
||||
self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.id)
|
||||
.where(lambda x: x.leaved_on is not None and x.joined_on is not None)
|
||||
.sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600),
|
||||
2,
|
||||
@@ -224,11 +214,7 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
guild: Guild = self._bot.guilds.where(lambda g: g == guild).single()
|
||||
channel = guild.get_channel(discord_channel_id)
|
||||
message = await channel.fetch_message(discord_message_id)
|
||||
emoji = (
|
||||
List(discord.Emoji, guild.emojis)
|
||||
.where(lambda x: x.name == rule.emoji_name)
|
||||
.single()
|
||||
)
|
||||
emoji = List(discord.Emoji, guild.emojis).where(lambda x: x.name == rule.emoji_name).single()
|
||||
|
||||
if emoji is None:
|
||||
self._logger.debug(__name__, f"Emoji {rule.emoji_name} not found")
|
||||
@@ -248,9 +234,7 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
||||
try:
|
||||
server = self._servers.get_server_by_discord_id(member.guild.id)
|
||||
settings: ServerConfig = self._config.get_configuration(
|
||||
f"ServerConfig_{server.discord_id}"
|
||||
)
|
||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.discord_id}")
|
||||
|
||||
if settings.default_role_id is None:
|
||||
return
|
||||
@@ -262,6 +246,11 @@ class ClientUtilsService(ClientUtilsABC):
|
||||
await member.add_roles(default_role)
|
||||
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__, f"Cannot check for default role for member {member.id}", e
|
||||
)
|
||||
self._logger.error(__name__, f"Cannot check for default role for member {member.id}", e)
|
||||
|
||||
async def set_maintenance_mode(self, state: bool):
|
||||
self._config.add_configuration(MAINTENANCE, state)
|
||||
if state:
|
||||
await self.presence_game("common.presence.maintenance")
|
||||
else:
|
||||
await self.presence_game("common.presence.running")
|
||||
|
@@ -7,6 +7,7 @@ from bot_data.abc.technician_config_repository_abc import TechnicianConfigReposi
|
||||
from bot_data.model.server import Server
|
||||
from bot_data.model.technician_config import TechnicianConfig
|
||||
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
||||
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
||||
|
||||
|
||||
class ConfigService:
|
||||
@@ -16,17 +17,24 @@ class ConfigService:
|
||||
services: ServiceProviderABC,
|
||||
technician_config_repo: TechnicianConfigRepositoryABC,
|
||||
server_config_repo: ServerConfigRepositoryABC,
|
||||
technician_seeder: TechnicianConfigSeeder,
|
||||
server_seeder: ServerConfigSeeder,
|
||||
):
|
||||
self._config = config
|
||||
self._services = services
|
||||
self._technician_config_repo = technician_config_repo
|
||||
self._technician_seeder = technician_seeder
|
||||
self._server_config_repo = server_config_repo
|
||||
|
||||
self._server_seeder = server_seeder
|
||||
|
||||
def reload_technician_config(self):
|
||||
technician_config = self._technician_config_repo.get_technician_config()
|
||||
async def reload_technician_config(self):
|
||||
try:
|
||||
technician_config = self._technician_config_repo.get_technician_config()
|
||||
except Exception as e:
|
||||
await self._technician_seeder.seed()
|
||||
technician_config = self._technician_config_repo.get_technician_config()
|
||||
|
||||
self._config.add_configuration(TechnicianConfig, technician_config)
|
||||
self._config.add_configuration(
|
||||
FeatureFlagsSettings,
|
||||
|
@@ -67,16 +67,12 @@ class DataIntegrityService:
|
||||
self._is_for_shutdown = False
|
||||
|
||||
def _check_known_users(self):
|
||||
self._logger.debug(
|
||||
__name__, f"Start checking KnownUsers table, {len(self._bot.users)}"
|
||||
)
|
||||
self._logger.debug(__name__, f"Start checking KnownUsers table, {len(self._bot.users)}")
|
||||
for u in self._bot.users:
|
||||
u: discord.User = u
|
||||
try:
|
||||
if u.bot:
|
||||
self._logger.trace(
|
||||
__name__, f"User {u.id} is ignored, because its a bot"
|
||||
)
|
||||
self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot")
|
||||
continue
|
||||
|
||||
user = self._known_users.find_user_by_discord_id(u.id)
|
||||
@@ -129,9 +125,7 @@ class DataIntegrityService:
|
||||
try:
|
||||
server: Server = self._servers.find_server_by_discord_id(g.id)
|
||||
if server is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"Server not found in database: {g.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"Server not found in database: {g.id}")
|
||||
|
||||
client = self._clients.find_client_by_server_id(server.id)
|
||||
if client is not None:
|
||||
@@ -142,9 +136,7 @@ class DataIntegrityService:
|
||||
f"Client for server {g.id} not found in database: {self._bot.user.id}",
|
||||
)
|
||||
self._logger.debug(__name__, f"Add client: {self._bot.user.id}")
|
||||
self._clients.add_client(
|
||||
Client(self._bot.user.id, 0, 0, 0, 0, 0, server)
|
||||
)
|
||||
self._clients.add_client(Client(self._bot.user.id, 0, 0, 0, 0, 0, server))
|
||||
self._db_context.save_changes()
|
||||
|
||||
client = self._clients.find_client_by_server_id(server.id)
|
||||
@@ -170,27 +162,21 @@ class DataIntegrityService:
|
||||
try:
|
||||
server = self._servers.find_server_by_discord_id(g.id)
|
||||
if server is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"Server not found in database: {g.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"Server not found in database: {g.id}")
|
||||
|
||||
for u in g.members:
|
||||
u: Union[discord.Member, discord.User] = u
|
||||
if u.bot:
|
||||
self._logger.trace(
|
||||
__name__, f"User {u.id} is ignored, because its a bot"
|
||||
)
|
||||
self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot")
|
||||
continue
|
||||
|
||||
user = self._users.find_user_by_discord_id_and_server_id(
|
||||
u.id, server.id
|
||||
)
|
||||
user = self._users.find_user_by_discord_id_and_server_id(u.id, server.id)
|
||||
if user is not None:
|
||||
continue
|
||||
|
||||
self._logger.warn(__name__, f"User not found in database: {u.id}")
|
||||
self._logger.debug(__name__, f"Add user: {u.id}")
|
||||
self._users.add_user(User(u.id, 0, 0, 0, server))
|
||||
self._users.add_user(User(u.id, 0, 0, 0, None, server))
|
||||
self._db_context.save_changes()
|
||||
|
||||
self._logger.debug(__name__, f"Added User: {u.id}")
|
||||
@@ -208,30 +194,20 @@ class DataIntegrityService:
|
||||
|
||||
server = self._servers.find_server_by_discord_id(guild.id)
|
||||
if server is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"Server not found in database: {guild.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
||||
|
||||
try:
|
||||
for u in guild.members:
|
||||
u: discord.User = u
|
||||
if u.bot:
|
||||
self._logger.trace(
|
||||
__name__, f"User {u.id} is ignored, because its a bot"
|
||||
)
|
||||
self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot")
|
||||
continue
|
||||
|
||||
user = self._users.find_user_by_discord_id_and_server_id(
|
||||
u.id, server.id
|
||||
)
|
||||
user = self._users.find_user_by_discord_id_and_server_id(u.id, server.id)
|
||||
if user is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"User not found in database: {u.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"User not found in database: {u.id}")
|
||||
|
||||
join = self._user_joins.find_active_user_joined_server_by_user_id(
|
||||
user.id
|
||||
)
|
||||
join = self._user_joins.find_active_user_joined_server_by_user_id(user.id)
|
||||
if join is not None:
|
||||
continue
|
||||
|
||||
@@ -281,36 +257,24 @@ class DataIntegrityService:
|
||||
self._logger.debug(__name__, f"Start checking UserJoinedVoiceChannel table")
|
||||
for guild in self._bot.guilds:
|
||||
guild: discord.Guild = guild
|
||||
settings: ServerConfig = self._config.get_configuration(
|
||||
f"ServerConfig_{guild.id}"
|
||||
)
|
||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
|
||||
|
||||
server = self._servers.find_server_by_discord_id(guild.id)
|
||||
if server is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"Server not found in database: {guild.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
||||
|
||||
try:
|
||||
# close open voice states
|
||||
for member in guild.members:
|
||||
if member.bot:
|
||||
self._logger.trace(
|
||||
__name__, f"User {member.id} is ignored, because its a bot"
|
||||
)
|
||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
||||
continue
|
||||
|
||||
user = self._users.find_user_by_discord_id_and_server_id(
|
||||
member.id, server.id
|
||||
)
|
||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
||||
if user is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"User not found in database: {member.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
||||
|
||||
joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(
|
||||
user.id
|
||||
)
|
||||
joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.id)
|
||||
if joins is None or len(joins) == 0:
|
||||
continue
|
||||
|
||||
@@ -324,9 +288,7 @@ class DataIntegrityService:
|
||||
if (
|
||||
(join.leaved_on - join.joined_on).total_seconds() / 60 / 60
|
||||
) > settings.max_voice_state_hours:
|
||||
join.leaved_on = join.joined_on + timedelta(
|
||||
hours=settings.max_voice_state_hours
|
||||
)
|
||||
join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours)
|
||||
|
||||
self._user_joins_vc.update_user_joined_voice_channel(join)
|
||||
|
||||
@@ -341,28 +303,17 @@ class DataIntegrityService:
|
||||
# add open voice states
|
||||
for member in guild.members:
|
||||
if member.bot:
|
||||
self._logger.trace(
|
||||
__name__, f"User {member.id} is ignored, because its a bot"
|
||||
)
|
||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
||||
continue
|
||||
|
||||
if (
|
||||
member.voice is None
|
||||
or member.voice.channel.id in settings.afk_channel_ids
|
||||
):
|
||||
if member.voice is None or member.voice.channel.id in settings.afk_channel_ids:
|
||||
continue
|
||||
|
||||
user = self._users.find_user_by_discord_id_and_server_id(
|
||||
member.id, server.id
|
||||
)
|
||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
||||
if user is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"User not found in database: {member.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
||||
|
||||
join = UserJoinedVoiceChannel(
|
||||
user, member.voice.channel.id, datetime.now()
|
||||
)
|
||||
join = UserJoinedVoiceChannel(user, member.voice.channel.id, datetime.now())
|
||||
self._user_joins_vc.add_user_joined_voice_channel(join)
|
||||
self._db_context.save_changes()
|
||||
|
||||
@@ -376,29 +327,19 @@ class DataIntegrityService:
|
||||
|
||||
server = self._servers.find_server_by_discord_id(guild.id)
|
||||
if server is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"Server not found in database: {guild.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
||||
|
||||
try:
|
||||
for member in guild.members:
|
||||
if member.bot:
|
||||
self._logger.trace(
|
||||
__name__, f"User {member.id} is ignored, because its a bot"
|
||||
)
|
||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
||||
continue
|
||||
|
||||
user = self._users.find_user_by_discord_id_and_server_id(
|
||||
member.id, server.id
|
||||
)
|
||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
||||
if user is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"User not found in database: {member.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
||||
|
||||
joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(
|
||||
user.id
|
||||
)
|
||||
joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.id)
|
||||
if joins is None or len(joins) == 0:
|
||||
continue
|
||||
|
||||
@@ -408,16 +349,12 @@ class DataIntegrityService:
|
||||
f"Active UserJoinedGameServer found in database: {guild.id}:{member.id}@{join.joined_on}",
|
||||
)
|
||||
join.leaved_on = datetime.now()
|
||||
settings: ServerConfig = self._config.get_configuration(
|
||||
f"ServerConfig_{guild.id}"
|
||||
)
|
||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
|
||||
|
||||
if (
|
||||
(join.leaved_on - join.joined_on).total_seconds() / 60 / 60
|
||||
) > settings.max_voice_state_hours:
|
||||
join.leaved_on = join.joined_on + timedelta(
|
||||
hours=settings.max_voice_state_hours
|
||||
)
|
||||
join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours)
|
||||
|
||||
self._user_joined_gs.update_user_joined_game_server(join)
|
||||
if self._is_for_shutdown:
|
||||
@@ -434,24 +371,16 @@ class DataIntegrityService:
|
||||
for guild in self._bot.guilds:
|
||||
server = self._servers.find_server_by_discord_id(guild.id)
|
||||
if server is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"Server not found in database: {guild.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
||||
|
||||
for member in guild.members:
|
||||
if member.bot:
|
||||
self._logger.trace(
|
||||
__name__, f"User {member.id} is ignored, because its a bot"
|
||||
)
|
||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
||||
continue
|
||||
|
||||
user = self._users.find_user_by_discord_id_and_server_id(
|
||||
member.id, server.id
|
||||
)
|
||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
||||
if user is None:
|
||||
self._logger.fatal(
|
||||
__name__, f"User not found in database: {member.id}"
|
||||
)
|
||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
||||
|
||||
await self._achievements.validate_achievements_for_user(user)
|
||||
|
||||
@@ -460,6 +389,22 @@ class DataIntegrityService:
|
||||
for member in guild.members:
|
||||
await self._client_utils.check_default_role(member)
|
||||
|
||||
def _check_for_bots(self):
|
||||
for guild in self._bot.guilds:
|
||||
server = self._servers.get_server_by_discord_id(guild.id)
|
||||
|
||||
for member in guild.members.where(lambda x: x.bot):
|
||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
||||
if user is None:
|
||||
continue
|
||||
|
||||
for join in self._user_joins.get_user_joined_servers_by_user_id(user.id):
|
||||
self._user_joins.delete_user_joined_server(join)
|
||||
|
||||
self._user_joins_vc.delete_user_joined_voice_channel_by_user_id(user.id)
|
||||
self._users.delete_user(user)
|
||||
self._db_context.save_changes()
|
||||
|
||||
async def check_data_integrity(self, is_for_shutdown=False):
|
||||
if is_for_shutdown != self._is_for_shutdown:
|
||||
self._is_for_shutdown = is_for_shutdown
|
||||
@@ -473,3 +418,4 @@ class DataIntegrityService:
|
||||
self._check_user_joins_vc()
|
||||
self._check_user_joined_gs()
|
||||
await self._check_for_user_achievements()
|
||||
self._check_for_bots()
|
||||
|
@@ -31,23 +31,15 @@ class MessageService(MessageServiceABC):
|
||||
self._clients = clients
|
||||
self._db = db
|
||||
|
||||
async def delete_messages(
|
||||
self, messages: List[discord.Message], guild_id: int, without_tracking=False
|
||||
):
|
||||
async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False):
|
||||
self._logger.debug(__name__, f"Try to delete {messages.count()} messages")
|
||||
server_st: ServerConfig = self._config.get_configuration(
|
||||
f"ServerConfig_{guild_id}"
|
||||
)
|
||||
server_st: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
|
||||
await asyncio.sleep(server_st.message_delete_timer)
|
||||
for message in messages:
|
||||
await self.delete_message(
|
||||
message, mass_delete=True, without_tracking=without_tracking
|
||||
)
|
||||
await self.delete_message(message, mass_delete=True, without_tracking=without_tracking)
|
||||
self._logger.debug(__name__, "Deleting messages finished")
|
||||
|
||||
async def delete_message(
|
||||
self, message: discord.Message, mass_delete=False, without_tracking=False
|
||||
):
|
||||
async def delete_message(self, message: discord.Message, mass_delete=False, without_tracking=False):
|
||||
guild_id = (
|
||||
message.guild.id
|
||||
if message.guild is not None
|
||||
@@ -58,9 +50,7 @@ class MessageService(MessageServiceABC):
|
||||
else None
|
||||
)
|
||||
|
||||
server_st: ServerConfig = self._config.get_configuration(
|
||||
f"ServerConfig_{guild_id}"
|
||||
)
|
||||
server_st: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
|
||||
if not mass_delete:
|
||||
await asyncio.sleep(server_st.message_delete_timer)
|
||||
self._logger.debug(
|
||||
@@ -74,9 +64,7 @@ class MessageService(MessageServiceABC):
|
||||
self._logger.error(__name__, f"Deleting message failed", e)
|
||||
else:
|
||||
if not without_tracking:
|
||||
self._clients.append_deleted_message_count(
|
||||
self._bot.user.id, guild_id, 1
|
||||
)
|
||||
self._clients.append_deleted_message_count(self._bot.user.id, guild_id, 1)
|
||||
self._db.save_changes()
|
||||
self._logger.info(__name__, f"Deleted message {message}")
|
||||
|
||||
@@ -88,9 +76,7 @@ class MessageService(MessageServiceABC):
|
||||
wait_before_delete: int = None,
|
||||
without_tracking=False,
|
||||
):
|
||||
self._logger.debug(
|
||||
__name__, f"Try to send message\n\t{message}\n\tto: {channel}"
|
||||
)
|
||||
self._logger.debug(__name__, f"Try to send message\n\t{message}\n\tto: {channel}")
|
||||
msg = None
|
||||
try:
|
||||
if isinstance(message, discord.Embed):
|
||||
@@ -100,15 +86,11 @@ class MessageService(MessageServiceABC):
|
||||
else:
|
||||
msg = await channel.send(message)
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__, f"Send message to channel {channel.id} failed", e
|
||||
)
|
||||
self._logger.error(__name__, f"Send message to channel {channel.id} failed", e)
|
||||
else:
|
||||
self._logger.info(__name__, f"Sent message to channel {channel.id}")
|
||||
if not without_tracking:
|
||||
self._clients.append_sent_message_count(
|
||||
self._bot.user.id, channel.guild.id, 1
|
||||
)
|
||||
self._clients.append_sent_message_count(self._bot.user.id, channel.guild.id, 1)
|
||||
self._db.save_changes()
|
||||
|
||||
if wait_before_delete is not None:
|
||||
@@ -125,23 +107,17 @@ class MessageService(MessageServiceABC):
|
||||
receiver: Union[discord.User, discord.Member],
|
||||
without_tracking=False,
|
||||
):
|
||||
self._logger.debug(
|
||||
__name__, f"Try to send message\n\t{message}\n\tto: {receiver}"
|
||||
)
|
||||
self._logger.debug(__name__, f"Try to send message\n\t{message}\n\tto: {receiver}")
|
||||
try:
|
||||
if isinstance(message, discord.Embed):
|
||||
msg = await receiver.send(embed=message)
|
||||
else:
|
||||
msg = await receiver.send(message)
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__, f"Send message to user {receiver.id} failed", e
|
||||
)
|
||||
self._logger.error(__name__, f"Send message to user {receiver.id} failed", e)
|
||||
else:
|
||||
if not without_tracking:
|
||||
self._clients.append_sent_message_count(
|
||||
self._bot.user.id, receiver.guild.id, 1
|
||||
)
|
||||
self._clients.append_sent_message_count(self._bot.user.id, receiver.guild.id, 1)
|
||||
self._db.save_changes()
|
||||
self._logger.info(__name__, f"Sent message to user {receiver.id}")
|
||||
|
||||
@@ -160,9 +136,7 @@ class MessageService(MessageServiceABC):
|
||||
self._logger.debug(__name__, f"Message: {message}")
|
||||
return None
|
||||
|
||||
self._logger.debug(
|
||||
__name__, f"Try to send message\t\t{message}\n\tto: {ctx.channel}"
|
||||
)
|
||||
self._logger.debug(__name__, f"Try to send message\t\t{message}\n\tto: {ctx.channel}")
|
||||
msg = None
|
||||
try:
|
||||
if isinstance(message, discord.Embed):
|
||||
@@ -170,15 +144,11 @@ class MessageService(MessageServiceABC):
|
||||
else:
|
||||
msg = await ctx.send(message, file=file, ephemeral=not is_public)
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__, f"Send message to channel {ctx.channel.id} failed", e
|
||||
)
|
||||
self._logger.error(__name__, f"Send message to channel {ctx.channel.id} failed", e)
|
||||
else:
|
||||
self._logger.info(__name__, f"Sent message to channel {ctx.channel.id}")
|
||||
if not without_tracking and ctx.guild is not None:
|
||||
self._clients.append_sent_message_count(
|
||||
self._bot.user.id, ctx.guild.id, 1
|
||||
)
|
||||
self._clients.append_sent_message_count(self._bot.user.id, ctx.guild.id, 1)
|
||||
self._db.save_changes()
|
||||
|
||||
if wait_before_delete is not None:
|
||||
@@ -207,30 +177,18 @@ class MessageService(MessageServiceABC):
|
||||
self._logger.debug(__name__, f"Message: {message}")
|
||||
return
|
||||
|
||||
self._logger.debug(
|
||||
__name__, f"Try to send message\t\t{message}\n\tto: {interaction.channel}"
|
||||
)
|
||||
self._logger.debug(__name__, f"Try to send message\t\t{message}\n\tto: {interaction.channel}")
|
||||
try:
|
||||
if isinstance(message, discord.Embed):
|
||||
await interaction.response.send_message(
|
||||
embed=message, ephemeral=not is_public, **kwargs
|
||||
)
|
||||
await interaction.response.send_message(embed=message, ephemeral=not is_public, **kwargs)
|
||||
else:
|
||||
await interaction.response.send_message(
|
||||
message, ephemeral=not is_public, **kwargs
|
||||
)
|
||||
await interaction.response.send_message(message, ephemeral=not is_public, **kwargs)
|
||||
except Exception as e:
|
||||
self._logger.error(
|
||||
__name__, f"Send message to channel {interaction.channel.id} failed", e
|
||||
)
|
||||
self._logger.error(__name__, f"Send message to channel {interaction.channel.id} failed", e)
|
||||
else:
|
||||
self._logger.info(
|
||||
__name__, f"Sent message to channel {interaction.channel.id}"
|
||||
)
|
||||
self._logger.info(__name__, f"Sent message to channel {interaction.channel.id}")
|
||||
if not without_tracking and interaction.guild is not None:
|
||||
self._clients.append_sent_message_count(
|
||||
self._bot.user.id, interaction.guild.id, 1
|
||||
)
|
||||
self._clients.append_sent_message_count(self._bot.user.id, interaction.guild.id, 1)
|
||||
self._db.save_changes()
|
||||
|
||||
if wait_before_delete is not None:
|
||||
@@ -239,6 +197,4 @@ class MessageService(MessageServiceABC):
|
||||
if is_persistent:
|
||||
return
|
||||
|
||||
await self.delete_message(
|
||||
await interaction.original_response(), without_tracking
|
||||
)
|
||||
await self.delete_message(await interaction.original_response(), without_tracking)
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_data"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_data.abc"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -28,9 +28,7 @@ class AchievementRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_user_got_achievements_by_achievement_id(
|
||||
self, achievement_id: int
|
||||
) -> List[Achievement]:
|
||||
def get_user_got_achievements_by_achievement_id(self, achievement_id: int) -> List[Achievement]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -23,9 +23,7 @@ class AuthUserRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_filtered_auth_users(
|
||||
self, criteria: AuthUserSelectCriteria
|
||||
) -> FilteredResult:
|
||||
def get_filtered_auth_users(self, criteria: AuthUserSelectCriteria) -> FilteredResult:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -36,9 +36,7 @@ class ClientRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_client_by_discord_id_and_server_id(
|
||||
self, discord_id: int, server_id: int
|
||||
) -> Optional[Client]:
|
||||
def find_client_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[Client]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -35,37 +35,25 @@ class ServerConfigRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_server_team_role_id_config(
|
||||
self, server_team_role_id: ServerTeamRoleIdsConfig
|
||||
):
|
||||
def add_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_server_team_role_id_config(
|
||||
self, server_team_role_id: ServerTeamRoleIdsConfig
|
||||
):
|
||||
def update_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_server_team_role_id_config(
|
||||
self, server_team_role_id: ServerTeamRoleIdsConfig
|
||||
):
|
||||
def delete_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_server_afk_channel_config(
|
||||
self, server_afk_channel: ServerAFKChannelIdsConfig
|
||||
):
|
||||
def add_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_server_afk_channel_config(
|
||||
self, server_afk_channel: ServerAFKChannelIdsConfig
|
||||
):
|
||||
def update_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_server_afk_channel_config(
|
||||
self, server_afk_channel: ServerAFKChannelIdsConfig
|
||||
):
|
||||
def delete_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
||||
pass
|
||||
|
@@ -43,19 +43,13 @@ class TechnicianConfigRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_technician_ping_url_config(
|
||||
self, technician_ping_url: TechnicianPingUrlConfig
|
||||
):
|
||||
def add_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_technician_ping_url_config(
|
||||
self, technician_ping_url: TechnicianPingUrlConfig
|
||||
):
|
||||
def update_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_technician_ping_url_config(
|
||||
self, technician_ping_url: TechnicianPingUrlConfig
|
||||
):
|
||||
def delete_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
||||
pass
|
||||
|
@@ -20,45 +20,31 @@ class UserJoinedGameServerRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_user_joined_game_servers_by_user_id(
|
||||
self, user_id: int
|
||||
) -> List[UserJoinedGameServer]:
|
||||
def get_user_joined_game_servers_by_user_id(self, user_id: int) -> List[UserJoinedGameServer]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_active_user_joined_game_server_by_user_id(
|
||||
self, user_id: int
|
||||
) -> UserJoinedGameServer:
|
||||
def get_active_user_joined_game_server_by_user_id(self, user_id: int) -> UserJoinedGameServer:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_active_user_joined_game_server_by_user_id(
|
||||
self, user_id: int
|
||||
) -> Optional[UserJoinedGameServer]:
|
||||
def find_active_user_joined_game_server_by_user_id(self, user_id: int) -> Optional[UserJoinedGameServer]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_active_user_joined_game_servers_by_user_id(
|
||||
self, user_id: int
|
||||
) -> List[Optional[UserJoinedGameServer]]:
|
||||
def find_active_user_joined_game_servers_by_user_id(self, user_id: int) -> List[Optional[UserJoinedGameServer]]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_user_joined_game_server(
|
||||
self, user_joined_game_server: UserJoinedGameServer
|
||||
):
|
||||
def add_user_joined_game_server(self, user_joined_game_server: UserJoinedGameServer):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_user_joined_game_server(
|
||||
self, user_joined_game_server: UserJoinedGameServer
|
||||
):
|
||||
def update_user_joined_game_server(self, user_joined_game_server: UserJoinedGameServer):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_user_joined_game_server(
|
||||
self, user_joined_game_server: UserJoinedGameServer
|
||||
):
|
||||
def delete_user_joined_game_server(self, user_joined_game_server: UserJoinedGameServer):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -24,21 +24,15 @@ class UserJoinedServerRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_user_joined_servers_by_user_id(
|
||||
self, user_id: int
|
||||
) -> list[UserJoinedServer]:
|
||||
def get_user_joined_servers_by_user_id(self, user_id: int) -> list[UserJoinedServer]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_active_user_joined_server_by_user_id(
|
||||
self, user_id: int
|
||||
) -> UserJoinedServer:
|
||||
def get_active_user_joined_server_by_user_id(self, user_id: int) -> UserJoinedServer:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_active_user_joined_server_by_user_id(
|
||||
self, user_id: int
|
||||
) -> Optional[UserJoinedServer]:
|
||||
def find_active_user_joined_server_by_user_id(self, user_id: int) -> Optional[UserJoinedServer]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -19,45 +19,31 @@ class UserJoinedVoiceChannelRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_user_joined_voice_channels_by_user_id(
|
||||
self, user_id: int
|
||||
) -> List[UserJoinedVoiceChannel]:
|
||||
def get_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[UserJoinedVoiceChannel]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_active_user_joined_voice_channel_by_user_id(
|
||||
self, user_id: int
|
||||
) -> UserJoinedVoiceChannel:
|
||||
def get_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> UserJoinedVoiceChannel:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_active_user_joined_voice_channel_by_user_id(
|
||||
self, user_id: int
|
||||
) -> Optional[UserJoinedVoiceChannel]:
|
||||
def find_active_user_joined_voice_channel_by_user_id(self, user_id: int) -> Optional[UserJoinedVoiceChannel]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_active_user_joined_voice_channels_by_user_id(
|
||||
self, user_id: int
|
||||
) -> List[Optional[UserJoinedVoiceChannel]]:
|
||||
def find_active_user_joined_voice_channels_by_user_id(self, user_id: int) -> List[Optional[UserJoinedVoiceChannel]]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_user_joined_voice_channel(
|
||||
self, user_joined_voice_channel: UserJoinedVoiceChannel
|
||||
):
|
||||
def add_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_user_joined_voice_channel(
|
||||
self, user_joined_voice_channel: UserJoinedVoiceChannel
|
||||
):
|
||||
def update_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete_user_joined_voice_channel(
|
||||
self, user_joined_voice_channel: UserJoinedVoiceChannel
|
||||
):
|
||||
def delete_user_joined_voice_channel(self, user_joined_voice_channel: UserJoinedVoiceChannel):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -17,9 +17,7 @@ class UserMessageCountPerHourRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_user_message_count_per_hour_by_user_id(
|
||||
self, user_id: int
|
||||
) -> Optional[UserMessageCountPerHour]:
|
||||
def find_user_message_count_per_hour_by_user_id(self, user_id: int) -> Optional[UserMessageCountPerHour]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -32,15 +32,11 @@ class UserRepositoryABC(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_user_by_discord_id_and_server_id(
|
||||
self, discord_id: int, server_id: int
|
||||
) -> User:
|
||||
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_user_by_discord_id_and_server_id(
|
||||
self, discord_id: int, server_id: int
|
||||
) -> Optional[User]:
|
||||
def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"Version": {
|
||||
"Major": "1",
|
||||
"Minor": "2",
|
||||
"Micro": "0"
|
||||
"Micro": "1"
|
||||
},
|
||||
"Author": "Sven Heidemann",
|
||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||
|
@@ -86,14 +86,10 @@ class DataModule(ModuleABC):
|
||||
def __init__(self, dc: DiscordCollectionABC):
|
||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.data_module)
|
||||
|
||||
def configure_configuration(
|
||||
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
||||
pass
|
||||
|
||||
def configure_services(
|
||||
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||
):
|
||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
||||
services.add_singleton(CacheService)
|
||||
|
||||
services.add_transient(ApiKeyRepositoryABC, ApiKeyRepositoryService)
|
||||
@@ -102,15 +98,9 @@ class DataModule(ModuleABC):
|
||||
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(
|
||||
UserJoinedGameServerRepositoryABC, UserJoinedGameServerRepositoryService
|
||||
)
|
||||
services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService)
|
||||
services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService)
|
||||
services.add_transient(UserJoinedGameServerRepositoryABC, UserJoinedGameServerRepositoryService)
|
||||
services.add_transient(AutoRoleRepositoryABC, AutoRoleRepositoryService)
|
||||
services.add_transient(LevelRepositoryABC, LevelRepositoryService)
|
||||
services.add_transient(UserWarningsRepositoryABC, UserWarningsRepositoryService)
|
||||
@@ -119,20 +109,12 @@ class DataModule(ModuleABC):
|
||||
UserMessageCountPerHourRepositoryService,
|
||||
)
|
||||
services.add_transient(GameServerRepositoryABC, GameServerRepositoryService)
|
||||
services.add_transient(
|
||||
UserGameIdentRepositoryABC, UserGameIdentRepositoryService
|
||||
)
|
||||
services.add_transient(UserGameIdentRepositoryABC, UserGameIdentRepositoryService)
|
||||
services.add_transient(AchievementRepositoryABC, AchievementRepositoryService)
|
||||
services.add_transient(
|
||||
TechnicianConfigRepositoryABC, TechnicianConfigRepositoryService
|
||||
)
|
||||
services.add_transient(TechnicianConfigRepositoryABC, TechnicianConfigRepositoryService)
|
||||
services.add_transient(ServerConfigRepositoryABC, ServerConfigRepositoryService)
|
||||
services.add_transient(
|
||||
ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService
|
||||
)
|
||||
services.add_transient(
|
||||
SteamSpecialOfferRepositoryABC, SteamSpecialOfferRepositoryService
|
||||
)
|
||||
services.add_transient(ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService)
|
||||
services.add_transient(SteamSpecialOfferRepositoryABC, SteamSpecialOfferRepositoryService)
|
||||
|
||||
services.add_transient(SeederService)
|
||||
services.add_transient(DataSeederABC, TechnicianConfigSeeder)
|
||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_data.migration"
|
||||
__author__ = "Sven Heidemann"
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.2.1"
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
||||
# imports
|
||||
|
||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||
version_info = VersionInfo(major="1", minor="2", micro="1")
|
||||
|
@@ -74,30 +74,12 @@ class AchievementsMigration(MigrationABC):
|
||||
|
||||
# A join table history between users and achievements is not necessary.
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""ALTER TABLE Users ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""
|
||||
)
|
||||
)
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""ALTER TABLE Users ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""
|
||||
)
|
||||
)
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""ALTER TABLE UsersHistory ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""
|
||||
)
|
||||
)
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""ALTER TABLE UsersHistory ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""
|
||||
)
|
||||
)
|
||||
self._cursor.execute(str(f"""ALTER TABLE Users ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
||||
self._cursor.execute(str(f"""ALTER TABLE Users ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
||||
self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
||||
self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
||||
|
||||
self._cursor.execute(
|
||||
str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;""")
|
||||
)
|
||||
self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;"""))
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
@@ -117,9 +99,7 @@ class AchievementsMigration(MigrationABC):
|
||||
)
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;""")
|
||||
)
|
||||
self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;"""))
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
|
@@ -16,15 +16,11 @@ class ConfigFeatureFlagsMigration(MigrationABC):
|
||||
self._logger.debug(__name__, "Running upgrade")
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
"""ALTER TABLE CFG_Technician ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;"""
|
||||
)
|
||||
str("""ALTER TABLE CFG_Technician ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;""")
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
"""ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;"""
|
||||
)
|
||||
str("""ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;""")
|
||||
)
|
||||
|
||||
def downgrade(self):
|
||||
|
@@ -5,6 +5,8 @@ CREATE TABLE IF NOT EXISTS `CFG_TechnicianHistory`
|
||||
`WaitForRestart` BIGINT NOT NULL DEFAULT 8,
|
||||
`WaitForShutdown` BIGINT NOT NULL DEFAULT 8,
|
||||
`CacheMaxMessages` BIGINT NOT NULL DEFAULT 1000000,
|
||||
`MaxSteamOfferCount` BIGINT NOT NULL DEFAULT 250,
|
||||
`Maintenance` BOOLEAN DEFAULT FALSE,
|
||||
`FeatureFlags` JSON NULL DEFAULT ('{}'),
|
||||
`Deleted` BOOL DEFAULT FALSE,
|
||||
`DateFrom` DATETIME(6) NOT NULL,
|
||||
@@ -23,6 +25,8 @@ BEGIN
|
||||
`WaitForRestart`,
|
||||
`WaitForShutdown`,
|
||||
`CacheMaxMessages`,
|
||||
`MaxSteamOfferCount`,
|
||||
`Maintenance`,
|
||||
`FeatureFlags`,
|
||||
`DateFrom`,
|
||||
`DateTo`)
|
||||
@@ -31,6 +35,8 @@ BEGIN
|
||||
OLD.WaitForRestart,
|
||||
OLD.WaitForShutdown,
|
||||
OLD.CacheMaxMessages,
|
||||
OLD.MaxSteamOfferCount,
|
||||
OLD.Maintenance,
|
||||
OLD.FeatureFlags,
|
||||
OLD.LastModifiedAt,
|
||||
CURRENT_TIMESTAMP(6));
|
||||
@@ -48,6 +54,8 @@ BEGIN
|
||||
`WaitForRestart`,
|
||||
`WaitForShutdown`,
|
||||
`CacheMaxMessages`,
|
||||
`MaxSteamOfferCount`,
|
||||
`Maintenance`,
|
||||
`FeatureFlags`,
|
||||
`Deleted`,
|
||||
`DateFrom`,
|
||||
@@ -57,6 +65,8 @@ BEGIN
|
||||
OLD.WaitForRestart,
|
||||
OLD.WaitForShutdown,
|
||||
OLD.CacheMaxMessages,
|
||||
OLD.MaxSteamOfferCount,
|
||||
OLD.Maintenance,
|
||||
OLD.FeatureFlags,
|
||||
TRUE,
|
||||
OLD.LastModifiedAt,
|
||||
|
@@ -47,7 +47,5 @@ class FixUpdatesMigration(MigrationABC):
|
||||
"""
|
||||
)
|
||||
)
|
||||
self._cursor.execute(
|
||||
"ALTER TABLE CFG_TechnicianHistory DROP COLUMN FeatureFlags;"
|
||||
)
|
||||
self._cursor.execute("ALTER TABLE CFG_TechnicianHistory DROP COLUMN FeatureFlags;")
|
||||
self._cursor.execute("ALTER TABLE CFG_ServerHistory DROP COLUMN FeatureFlags;")
|
||||
|
@@ -17,14 +17,10 @@ class FixUserHistoryMigration(MigrationABC):
|
||||
|
||||
# fix 1.1.0_AchievementsMigration
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""ALTER TABLE UsersHistory ADD COLUMN IF NOT EXISTS ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""
|
||||
)
|
||||
str(f"""ALTER TABLE UsersHistory ADD COLUMN ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")
|
||||
)
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""ALTER TABLE UsersHistory ADD COLUMN IF NOT EXISTS MessageCount BIGINT NOT NULL DEFAULT 0 AFTER ReactionCount;"""
|
||||
)
|
||||
str(f"""ALTER TABLE UsersHistory ADD COLUMN MessageCount BIGINT NOT NULL DEFAULT 0 AFTER ReactionCount;""")
|
||||
)
|
||||
self._exec(__file__, "users.sql")
|
||||
|
||||
|
51
bot/src/bot_data/migration/maintenance_mode_migration.py
Normal file
51
bot/src/bot_data/migration/maintenance_mode_migration.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.migration_abc import MigrationABC
|
||||
from bot_data.db_context import DBContext
|
||||
|
||||
|
||||
class MaintenanceModeMigration(MigrationABC):
|
||||
name = "1.2.0_MaintenanceModeMigration"
|
||||
|
||||
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"""
|
||||
ALTER TABLE CFG_Technician
|
||||
ADD Maintenance BOOLEAN DEFAULT FALSE AFTER MaxSteamOfferCount;
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_TechnicianHistory
|
||||
ADD Maintenance BOOLEAN DEFAULT FALSE AFTER MaxSteamOfferCount;
|
||||
"""
|
||||
)
|
||||
)
|
||||
self._exec(__file__, "config/technician.sql")
|
||||
|
||||
def downgrade(self):
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_Technician DROP COLUMN Maintenance;
|
||||
"""
|
||||
)
|
||||
)
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_TechnicianHistory DROP COLUMN Maintenance;
|
||||
"""
|
||||
)
|
||||
)
|
@@ -0,0 +1,51 @@
|
||||
from bot_core.logging.database_logger import DatabaseLogger
|
||||
from bot_data.abc.migration_abc import MigrationABC
|
||||
from bot_data.db_context import DBContext
|
||||
|
||||
|
||||
class MaxSteamOfferCountMigration(MigrationABC):
|
||||
name = "1.2.0_MaxSteamOfferCountMigration"
|
||||
|
||||
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"""
|
||||
ALTER TABLE CFG_Technician
|
||||
ADD MaxSteamOfferCount BIGINT NOT NULL DEFAULT 250 AFTER CacheMaxMessages;
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_TechnicianHistory
|
||||
ADD MaxSteamOfferCount BIGINT NOT NULL DEFAULT 250 AFTER CacheMaxMessages;
|
||||
"""
|
||||
)
|
||||
)
|
||||
self._exec(__file__, "config/technician.sql")
|
||||
|
||||
def downgrade(self):
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_Technician DROP COLUMN MaxSteamOfferCount;
|
||||
"""
|
||||
)
|
||||
)
|
||||
self._cursor.execute(
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_TechnicianHistory DROP COLUMN MaxSteamOfferCount;
|
||||
"""
|
||||
)
|
||||
)
|
@@ -36,7 +36,7 @@ class SteamSpecialOfferMigration(MigrationABC):
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_Server
|
||||
ADD COLUMN IF NOT EXISTS GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;
|
||||
ADD COLUMN GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;
|
||||
"""
|
||||
)
|
||||
)
|
||||
@@ -45,7 +45,7 @@ class SteamSpecialOfferMigration(MigrationABC):
|
||||
str(
|
||||
f"""
|
||||
ALTER TABLE CFG_ServerHistory
|
||||
ADD COLUMN IF NOT EXISTS GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;
|
||||
ADD COLUMN GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user