30 Commits
1.2.4 ... dev

Author SHA1 Message Date
266dacb301 Fixed deps
All checks were successful
Deploy staging on push / pre-build (push) Successful in 2s
Deploy staging on push / build-bot (push) Successful in 3m12s
Deploy staging on push / build-web (push) Successful in 2m1s
Deploy staging on push / deploy (push) Successful in 26s
Deploy dev on push / pre-build (push) Successful in 2s
Deploy dev on push / build-bot (push) Successful in 1m55s
Deploy dev on push / build-web (push) Successful in 1m46s
Deploy dev on push / deploy (push) Successful in 23s
2023-12-13 12:11:09 +01:00
280cd9827d shutdown correct stack
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 2m1s
Deploy staging on push / build-web (push) Successful in 1m57s
Deploy staging on push / deploy (push) Successful in 22s
2023-12-13 11:59:21 +01:00
36998470e8 Try filtering scheduled events
All checks were successful
Deploy staging on push / pre-build (push) Successful in 2s
Deploy staging on push / build-bot (push) Successful in 3m0s
Deploy staging on push / build-web (push) Successful in 2m7s
Deploy staging on push / deploy (push) Successful in 24s
2023-12-13 11:25:51 +01:00
53c6bf4208 Merge pull request 'Added gmod support #277' (#459) from #277 into staging
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 3m8s
Deploy staging on push / build-web (push) Successful in 1m47s
Deploy staging on push / deploy (push) Successful in 24s
Reviewed-on: #459
2023-12-12 11:49:43 +01:00
4e80e3ccb7 Added gmod support #277 2023-12-11 21:34:38 +01:00
ba173a6743 Improved xp knob #409
All checks were successful
Deploy staging on push / pre-build (push) Successful in 2s
Deploy staging on push / build-bot (push) Successful in 3m4s
Deploy staging on push / build-web (push) Successful in 1m56s
Deploy staging on push / deploy (push) Successful in 26s
2023-12-10 19:50:44 +01:00
84ff2a8a9b Fixed update user #455 2023-12-10 19:18:20 +01:00
13bc38fea8 Updated profile #409 2023-12-10 19:00:00 +01:00
dfdf0555d7 Added feature flag check for scheduled events #455
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 3m6s
Deploy staging on push / build-web (push) Successful in 1m57s
Deploy staging on push / deploy (push) Successful in 28s
2023-12-10 17:08:26 +01:00
39299eb11b Made watchers transient
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 3m46s
Deploy staging on push / build-web (push) Successful in 2m5s
Deploy staging on push / deploy (push) Successful in 28s
2023-12-10 13:13:24 +01:00
dfb6751bf9 Set event watcher loop from 12 to 3 hours
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 2m52s
Deploy staging on push / build-web (push) Successful in 1m53s
Deploy staging on push / deploy (push) Successful in 32s
2023-12-10 11:18:30 +01:00
4a75635a55 Fixed actions
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 1m47s
Deploy staging on push / build-web (push) Successful in 1m42s
Deploy staging on push / deploy (push) Successful in 22s
2023-12-09 22:48:37 +01:00
f6b2739394 Merge pull request 'Fixed actions' (#458) from dev into staging
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 1m52s
Deploy staging on push / build-web (push) Successful in 1m44s
Deploy staging on push / deploy (push) Successful in 23s
Reviewed-on: #458
2023-12-09 22:38:35 +01:00
36d2605655 Merge branch 'staging' into dev
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 1m53s
Deploy dev on push / build-web (push) Successful in 1m47s
Deploy dev on push / deploy (push) Successful in 21s
2023-12-09 22:38:16 +01:00
af891fa588 Fixed actions
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 1m51s
Deploy dev on push / build-web (push) Successful in 1m50s
Deploy dev on push / deploy (push) Successful in 23s
2023-12-09 22:33:14 +01:00
af348b85a4 Merge pull request 'dev into staging' (#457) from dev into staging
All checks were successful
Deploy staging on push / pre-build (push) Successful in 1s
Deploy staging on push / build-bot (push) Successful in 1m46s
Deploy staging on push / build-web (push) Successful in 1m44s
Deploy staging on push / deploy (push) Successful in 27s
Reviewed-on: #457
2023-12-09 22:23:06 +01:00
7ed621a25b Fixed actions
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 1m52s
Deploy dev on push / build-web (push) Successful in 1m41s
Deploy dev on push / deploy (push) Successful in 21s
2023-12-09 22:17:56 +01:00
013f953a7f Fixed actions
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 1m53s
Deploy dev on push / build-web (push) Successful in 1m42s
Deploy dev on push / deploy (push) Successful in 23s
2023-12-09 22:10:04 +01:00
4163532696 Fixed actions
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 1m52s
Deploy dev on push / build-web (push) Successful in 1m57s
Deploy dev on push / deploy (push) Successful in 6s
2023-12-09 22:02:57 +01:00
b6a1172cc1 Fixed actions
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 2m0s
Deploy dev on push / build-web (push) Successful in 1m47s
Deploy dev on push / deploy (push) Successful in 6s
2023-12-09 21:51:47 +01:00
20bdb6bd98 Updated compose files
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 2m1s
Deploy dev on push / build-web (push) Successful in 1m42s
Deploy dev on push / deploy (push) Successful in 5s
2023-12-09 21:46:01 +01:00
3f13f65932 Updated other env actions 2023-12-09 21:43:34 +01:00
711e184895 Fixed dev action
All checks were successful
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 1m48s
Deploy dev on push / build-web (push) Successful in 1m53s
Deploy dev on push / deploy (push) Successful in 5s
2023-12-09 21:34:21 +01:00
7e3975f4be Fixed dev action
Some checks failed
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Successful in 2m13s
Deploy dev on push / build-web (push) Successful in 1m43s
Deploy dev on push / deploy (push) Failing after 1s
2023-12-09 21:28:15 +01:00
d4f4f39522 Fixed dev action
Some checks failed
Deploy dev on push / pre-build (push) Successful in 1s
Deploy dev on push / build-bot (push) Failing after 1m55s
Deploy dev on push / build-web (push) Failing after 1m45s
Deploy dev on push / deploy (push) Has been skipped
2023-12-09 21:22:00 +01:00
af9c55e4b1 Updated dev action
Some checks failed
Deploy dev on push / pre-build (push) Successful in 2s
Deploy dev on push / build-bot (push) Failing after 2m3s
Deploy dev on push / build-web (push) Failing after 2m5s
Deploy dev on push / deploy (push) Has been skipped
2023-12-09 21:00:20 +01:00
e3172d6f24 Fixed event logger
All checks were successful
Deploy staging on push / on-push-deploy_sh-edraft (push) Successful in 4m22s
2023-12-09 14:11:34 +01:00
0706579f62 Fixed set timestamp for scheduled events #456
All checks were successful
Deploy staging on push / on-push-deploy_sh-edraft (push) Successful in 4m9s
2023-12-09 14:05:35 +01:00
ad3fc94923 Improved logging for event_service
All checks were successful
Deploy staging on push / on-push-deploy_sh-edraft (push) Successful in 4m13s
2023-12-09 13:58:38 +01:00
69882af0bd Added event logger
Some checks reported warnings
Deploy staging on push / on-push-deploy_sh-edraft (push) Has been cancelled
2023-12-09 13:55:40 +01:00
49 changed files with 556 additions and 235 deletions

View File

@@ -6,9 +6,17 @@ on:
- dev - dev
jobs: jobs:
on-push-deploy_sh-edraft: pre-build:
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: sh-edraft.de/act-runner:latest container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Shutdown stack
run: docker stack rm sdb_dev
build-bot:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps: steps:
- name: Setup docker - name: Setup docker
uses: https://github.com/papodaca/install-docker-action@main uses: https://github.com/papodaca/install-docker-action@main
@@ -22,10 +30,44 @@ jobs:
- name: Prepare bot build - name: Prepare bot build
run: | run: |
cd bot
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
cd bot
cpl i cpl i
- name: Build docker bot
run: |
cd bot
docker image prune -f
cpl build
docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-dev .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd bot
docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-dev
build-web:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/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: Setup node - name: Setup node
uses: https://github.com/actions/setup-node@v3 uses: https://github.com/actions/setup-node@v3
@@ -35,29 +77,45 @@ jobs:
npm install -g ts-node npm install -g ts-node
npm ci 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 - name: Build docker web
run: | run: |
cd web cd web
docker image prune -f docker image prune -f
cp src/favicon.dev.ico src/favicon.ico cp src/favicon.dev.ico src/favicon.ico
npm run build npm run build
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-dev . docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-dev .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd web
docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-dev
deploy:
needs: [ build-bot, build-web ]
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- name: Install cpl
run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
- name: Set version - name: Set version
run: | run: |
cd bot/docker cd bot/docker
chmod +x ./set-docker-compose-image-version.sh 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 ./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-dev git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-dev
- name: Deploy Stack to sh-edraft.de - name: Deploy Stack to sh-edraft.de
uses: https://github.com/kgierke/portainer-stack-deployment@v1 uses: https://github.com/kgierke/portainer-stack-deployment@v1

View File

@@ -6,9 +6,17 @@ on:
- master - master
jobs: jobs:
on-push-deploy_sh-edraft: pre-build:
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: sh-edraft.de/act-runner:latest container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Shutdown stack
run: docker stack rm sdb_prod
build-bot:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps: steps:
- name: Setup docker - name: Setup docker
uses: https://github.com/papodaca/install-docker-action@main uses: https://github.com/papodaca/install-docker-action@main
@@ -22,10 +30,44 @@ jobs:
- name: Prepare bot build - name: Prepare bot build
run: | run: |
cd bot
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
cd bot
cpl i cpl i
- name: Build docker bot
run: |
cd bot
docker image prune -f
cpl build
docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv) .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd bot
docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)
build-web:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/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: Setup node - name: Setup node
uses: https://github.com/actions/setup-node@v3 uses: https://github.com/actions/setup-node@v3
@@ -35,28 +77,45 @@ jobs:
npm install -g ts-node npm install -g ts-node
npm ci 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 - name: Build docker web
run: | run: |
cd web cd web
docker image prune -f docker image prune -f
cp src/favicon.ico src/favicon.ico
npm run build npm run build
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv) . docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv) .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd web
docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)
deploy:
needs: [ build-bot, build-web ]
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- name: Install cpl
run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
- name: Set version - name: Set version
run: | run: |
cd bot/docker cd bot/docker
chmod +x ./set-docker-compose-image-version.sh 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;) ./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv) git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)
- name: Deploy Stack to sh-edraft.de - name: Deploy Stack to sh-edraft.de
uses: https://github.com/kgierke/portainer-stack-deployment@v1 uses: https://github.com/kgierke/portainer-stack-deployment@v1

View File

@@ -6,9 +6,17 @@ on:
- staging - staging
jobs: jobs:
on-push-deploy_sh-edraft: pre-build:
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: sh-edraft.de/act-runner:latest container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Shutdown stack
run: docker stack rm sdb_staging
build-bot:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps: steps:
- name: Setup docker - name: Setup docker
uses: https://github.com/papodaca/install-docker-action@main uses: https://github.com/papodaca/install-docker-action@main
@@ -22,10 +30,44 @@ jobs:
- name: Prepare bot build - name: Prepare bot build
run: | run: |
cd bot
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
cd bot
cpl i cpl i
- name: Build docker bot
run: |
cd bot
docker image prune -f
cpl build
docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-staging .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd bot
docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-staging
build-web:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/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: Setup node - name: Setup node
uses: https://github.com/actions/setup-node@v3 uses: https://github.com/actions/setup-node@v3
@@ -35,29 +77,45 @@ jobs:
npm install -g ts-node npm install -g ts-node
npm ci 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 - name: Build docker web
run: | run: |
cd web cd web
docker image prune -f docker image prune -f
cp src/favicon.staging.ico src/favicon.ico cp src/favicon.staging.ico src/favicon.ico
npm run build npm run build
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-staging . docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-staging .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd web
docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-staging
deploy:
needs: [ build-bot, build-web ]
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- name: Install cpl
run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
- name: Set version - name: Set version
run: | run: |
cd bot/docker cd bot/docker
chmod +x ./set-docker-compose-image-version.sh 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 ./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-staging git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-staging
- name: Deploy Stack to sh-edraft.de - name: Deploy Stack to sh-edraft.de
uses: https://github.com/kgierke/portainer-stack-deployment@v1 uses: https://github.com/kgierke/portainer-stack-deployment@v1

View File

@@ -33,7 +33,8 @@
"cryptography==41.0.4", "cryptography==41.0.4",
"discord==2.3.2", "discord==2.3.2",
"bs4==0.0.1", "bs4==0.0.1",
"lxml==4.9.3" "lxml==4.9.3",
"python-valve==0.2.1"
], ],
"DevDependencies": [ "DevDependencies": [
"cpl-cli==2023.4.0.post3", "cpl-cli==2023.4.0.post3",

View File

@@ -15,6 +15,7 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.logging.command_logger import CommandLogger from bot_core.logging.command_logger import CommandLogger
from bot_core.logging.database_logger import DatabaseLogger from bot_core.logging.database_logger import DatabaseLogger
from bot_core.logging.event_logger import EventLogger
from bot_core.logging.message_logger import MessageLogger from bot_core.logging.message_logger import MessageLogger
from bot_core.logging.task_logger import TaskLogger from bot_core.logging.task_logger import TaskLogger
from bot_data.db_context import DBContext from bot_data.db_context import DBContext
@@ -45,6 +46,7 @@ class Startup(StartupABC):
services.add_singleton(CustomFileLoggerABC, DatabaseLogger) services.add_singleton(CustomFileLoggerABC, DatabaseLogger)
services.add_singleton(CustomFileLoggerABC, MessageLogger) services.add_singleton(CustomFileLoggerABC, MessageLogger)
services.add_singleton(CustomFileLoggerABC, TaskLogger) services.add_singleton(CustomFileLoggerABC, TaskLogger)
services.add_singleton(CustomFileLoggerABC, EventLogger)
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module): if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
services.add_singleton(CustomFileLoggerABC, ApiLogger) services.add_singleton(CustomFileLoggerABC, ApiLogger)

View File

@@ -1,20 +1,18 @@
import asyncio
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.logging import LoggerABC
from cpl_discord.events import OnReadyABC from cpl_discord.events import OnReadyABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from cpl_translation import TranslatePipe from cpl_translation import TranslatePipe
from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.client_utils_abc import ClientUtilsABC
from bot_core.environment_variables import MAINTENANCE from bot_core.environment_variables import MAINTENANCE
from bot_core.logging.event_logger import EventLogger
class CoreExtensionOnReadyEvent(OnReadyABC): class CoreExtensionOnReadyEvent(OnReadyABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
client_utils: ClientUtilsABC, client_utils: ClientUtilsABC,
t: TranslatePipe, t: TranslatePipe,

View File

@@ -1,15 +1,15 @@
from cpl_core.logging import LoggerABC
from cpl_discord.events import OnReadyABC from cpl_discord.events import OnReadyABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from cpl_translation import TranslatePipe from cpl_translation import TranslatePipe
from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.client_utils_abc import ClientUtilsABC
from bot_core.logging.event_logger import EventLogger
class CoreOnReadyEvent(OnReadyABC): class CoreOnReadyEvent(OnReadyABC):
def __init__( def __init__(
self, self,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
client_utils: ClientUtilsABC, client_utils: ClientUtilsABC,
t: TranslatePipe, t: TranslatePipe,

View File

@@ -0,0 +1,15 @@
from cpl_core.configuration import ConfigurationABC
from cpl_core.environment import ApplicationEnvironmentABC
from cpl_core.time import TimeFormatSettings
from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC
class EventLogger(CustomFileLoggerABC):
def __init__(
self,
config: ConfigurationABC,
time_format: TimeFormatSettings,
env: ApplicationEnvironmentABC,
):
CustomFileLoggerABC.__init__(self, "Event", config, time_format, env)

View File

@@ -168,6 +168,13 @@ class User(TableABC):
game_idents_repo: UserGameIdentRepositoryABC = services.get_service(UserGameIdentRepositoryABC) game_idents_repo: UserGameIdentRepositoryABC = services.get_service(UserGameIdentRepositoryABC)
return game_idents_repo.get_user_game_idents_by_user_id(self.id) return game_idents_repo.get_user_game_idents_by_user_id(self.id)
@property
@ServiceProviderABC.inject
def profile_picture_url(self, bot: DiscordBotServiceABC) -> str:
guild = bot.get_guild(self.server.discord_id)
user = guild.get_member(self._discord_id)
return None if user is None else user.avatar.url
@staticmethod @staticmethod
def get_select_all_string() -> str: def get_select_all_string() -> str:
return str( return str(

View File

@@ -11,6 +11,8 @@ type User implements TableWithHistoryQuery {
level: Level level: Level
activityScore: Int activityScore: Int
profilePictureURL: String
joinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [UserJoinedServer] joinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [UserJoinedServer]
joinedServerCount: Int joinedServerCount: Int

View File

@@ -11,6 +11,7 @@ from flask import request
from bot_api.configuration.authentication_settings import AuthenticationSettings from bot_api.configuration.authentication_settings import AuthenticationSettings
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.service.permission_service import PermissionService
from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC
from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
@@ -24,7 +25,6 @@ from bot_data.model.server_config import ServerConfig
from bot_data.model.user_joined_game_server import UserJoinedGameServer from bot_data.model.user_joined_game_server import UserJoinedGameServer
from bot_data.model.user_role_enum import UserRoleEnum from bot_data.model.user_role_enum import UserRoleEnum
from bot_graphql.abc.query_abc import QueryABC from bot_graphql.abc.query_abc import QueryABC
from bot_core.service.permission_service import PermissionService
class UserJoinedGameServerMutation(QueryABC): class UserJoinedGameServerMutation(QueryABC):
@@ -79,7 +79,10 @@ class UserJoinedGameServerMutation(QueryABC):
) )
def resolve_user_joined(self, *_, input: dict): def resolve_user_joined(self, *_, input: dict):
game_ident = self._user_game_idents.get_user_game_ident_by_ident(input["ident"]) game_ident = self._user_game_idents.find_user_game_ident_by_ident(input["ident"])
if game_ident is None:
return
user = game_ident.user user = game_ident.user
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{user.server.discord_id}") settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{user.server.discord_id}")

View File

@@ -4,6 +4,7 @@ from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from bot_api.route.route import Route from bot_api.route.route import Route
from bot_core.service.permission_service import PermissionService
from bot_data.abc.level_repository_abc import LevelRepositoryABC from bot_data.abc.level_repository_abc import LevelRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC
@@ -13,7 +14,6 @@ from bot_data.model.user_role_enum import UserRoleEnum
from bot_graphql.abc.query_abc import QueryABC from bot_graphql.abc.query_abc import QueryABC
from modules.base.service.user_warnings_service import UserWarningsService from modules.base.service.user_warnings_service import UserWarningsService
from modules.level.service.level_service import LevelService from modules.level.service.level_service import LevelService
from bot_core.service.permission_service import PermissionService
class UserMutation(QueryABC): class UserMutation(QueryABC):
@@ -50,7 +50,7 @@ class UserMutation(QueryABC):
member = self._bot.get_guild(user.server.discord_id).get_member( member = self._bot.get_guild(user.server.discord_id).get_member(
auth_user.users.where(lambda x: x.server.id == user.server.id).single().discord_id auth_user.users.where(lambda x: x.server.id == user.server.id).single().discord_id
) )
if member.id != user.discord_id: if self._permissions.is_member_moderator(member) or member.id != user.discord_id:
self._can_user_mutate_data(user.server, UserRoleEnum.moderator) self._can_user_mutate_data(user.server, UserRoleEnum.moderator)
new_xp = None new_xp = None

View File

@@ -88,3 +88,4 @@ class UserQuery(DataQueryWithHistoryABC):
self.set_field("server", lambda user, *_: user.server) self.set_field("server", lambda user, *_: user.server)
self.set_field("leftServer", lambda user, *_: user.left_server) self.set_field("leftServer", lambda user, *_: user.left_server)
self.set_field("profilePictureURL", lambda user, *_: user.profile_picture_url)

View File

@@ -62,8 +62,8 @@ class BaseModule(ModuleABC):
services.add_transient(BaseReactionHandler) services.add_transient(BaseReactionHandler)
services.add_singleton(EventService) services.add_singleton(EventService)
services.add_transient(UserWarningsService) services.add_transient(UserWarningsService)
services.add_singleton(TaskABC, BirthdayWatcher) services.add_transient(TaskABC, BirthdayWatcher)
services.add_singleton(TaskABC, ScheduledEventsWatcher) services.add_transient(TaskABC, ScheduledEventsWatcher)
# forms # forms
services.add_transient(BugReportForm) services.add_transient(BugReportForm)

View File

@@ -9,6 +9,7 @@ from cpl_translation import TranslatePipe
from discord import app_commands from discord import app_commands
from discord.ext import commands from discord.ext import commands
from discord.ext.commands import Context from discord.ext.commands import Context
from valve.steam.id import SteamID
from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.client_utils_abc import ClientUtilsABC
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
@@ -50,6 +51,17 @@ class RegisterGroup(DiscordCommandABC):
self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}")
async def _game_server_autocomplete(
self, interaction: discord.Interaction, current: str
) -> TList[app_commands.Choice[str]]:
server = self._servers.get_server_by_discord_id(interaction.guild.id)
game_servers = self._game_server.get_game_servers_by_server_id(server.id)
return [
app_commands.Choice(name=gs.name, value=gs.id)
for gs in self._client_utils.get_auto_complete_list(game_servers, current, lambda x: x.name)
]
@commands.hybrid_group() @commands.hybrid_group()
@commands.guild_only() @commands.guild_only()
async def register(self, ctx: Context): async def register(self, ctx: Context):
@@ -101,10 +113,44 @@ class RegisterGroup(DiscordCommandABC):
async def game_server_autocomplete( async def game_server_autocomplete(
self, interaction: discord.Interaction, current: str self, interaction: discord.Interaction, current: str
) -> TList[app_commands.Choice[str]]: ) -> TList[app_commands.Choice[str]]:
server = self._servers.get_server_by_discord_id(interaction.guild.id) return await self._game_server_autocomplete(interaction, current)
game_servers = self._game_server.get_game_servers_by_server_id(server.id)
return [ @register.command()
app_commands.Choice(name=gs.name, value=gs.id) @commands.guild_only()
for gs in self._client_utils.get_auto_complete_list(game_servers, current, lambda x: x.name) @CommandChecks.check_is_ready()
] @CommandChecks.check_is_member_moderator()
async def gmod(self, ctx: Context, member: discord.Member, game_server: int, steam_url: str):
self._logger.debug(__name__, f"Received command register gmod {ctx}")
steam_id = None
try:
self._logger.debug(__name__, f"Try to get steam id for {id}")
steam_id = SteamID.from_community_url(steam_url)
except Exception as e:
self._logger.error(__name__, f"Get steam id for {steam_id} failed", e)
await self._message_service.send_interaction_msg(
ctx.interaction, self._t.transform("modules.base.register.not_found")
)
if steam_id is None:
return
server = self._servers.get_server_by_discord_id(ctx.guild.id)
user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id)
gs = self._game_server.get_game_server_by_id(game_server)
game_ident = UserGameIdent(user, gs, steam_id)
self._user_game_ident.add_user_game_ident(game_ident)
self._db.save_changes()
await self._message_service.send_interaction_msg(
ctx.interaction, self._t.transform("modules.base.register.success")
)
self._logger.trace(__name__, f"Finished register gmod command")
@gmod.autocomplete("game_server")
async def game_server_autocomplete(
self, interaction: discord.Interaction, current: str
) -> TList[app_commands.Choice[str]]:
return await self._game_server_autocomplete(interaction, current)

View File

@@ -1,22 +1,34 @@
from cpl_core.configuration import ConfigurationABC
from cpl_discord.command import DiscordCommandABC from cpl_discord.command import DiscordCommandABC
from cpl_translation import TranslatePipe
from discord.ext import commands from discord.ext import commands
from discord.ext.commands import Context from discord.ext.commands import Context
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.helper.command_checks import CommandChecks from bot_core.helper.command_checks import CommandChecks
from bot_core.logging.command_logger import CommandLogger from bot_core.logging.command_logger import CommandLogger
from bot_core.service.message_service import MessageService
from bot_data.model.server_config import ServerConfig
from modules.base.service.event_service import EventService from modules.base.service.event_service import EventService
class ScheduledEventsCommand(DiscordCommandABC): class ScheduledEventsCommand(DiscordCommandABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC,
logger: CommandLogger, logger: CommandLogger,
events: EventService, events: EventService,
message_service: MessageService,
t: TranslatePipe,
): ):
DiscordCommandABC.__init__(self) DiscordCommandABC.__init__(self)
self._config = config
self._logger = logger self._logger = logger
self._events = events self._events = events
self._message_service = message_service
self._t = t
self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}")
@@ -30,6 +42,12 @@ class ScheduledEventsCommand(DiscordCommandABC):
@CommandChecks.check_is_ready() @CommandChecks.check_is_ready()
@CommandChecks.check_is_member_moderator() @CommandChecks.check_is_member_moderator()
async def reload(self, ctx: Context): async def reload(self, ctx: Context):
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}")
if not FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum.scheduled_events):
self._logger.debug(__name__, f"Skipping scheduled event check for {ctx.guild.id}. Feature is disabled.")
await self._message_service.send_ctx_msg(ctx, self._t.transform("common.feature_not_activated"))
return
self._logger.debug(__name__, "Running scheduled-events reload") self._logger.debug(__name__, "Running scheduled-events reload")
try: try:
await self._events.check_and_create_scheduled_events(ctx.guild) await self._events.check_and_create_scheduled_events(ctx.guild)

View File

@@ -1,7 +1,6 @@
import datetime import datetime
import uuid import uuid
from cpl_core.logging import LoggerABC
from cpl_core.time import TimeFormatSettings from cpl_core.time import TimeFormatSettings
from cpl_discord.events.on_command_error_abc import OnCommandErrorABC from cpl_discord.events.on_command_error_abc import OnCommandErrorABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
@@ -12,13 +11,14 @@ from discord.ext.commands import Context, CommandError
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.exception.check_error import CheckError from bot_core.exception.check_error import CheckError
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.model.technician_config import TechnicianConfig from bot_data.model.technician_config import TechnicianConfig
class BaseOnCommandErrorEvent(OnCommandErrorABC): class BaseOnCommandErrorEvent(OnCommandErrorABC):
def __init__( def __init__(
self, self,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
messenger: MessageServiceABC, messenger: MessageServiceABC,
tech_settings: TechnicianConfig, tech_settings: TechnicianConfig,

View File

@@ -1,10 +1,10 @@
from cpl_core.database.context import DatabaseContextABC from cpl_core.database.context import DatabaseContextABC
from cpl_core.logging import LoggerABC
from cpl_discord.events import OnGuildJoinABC from cpl_discord.events import OnGuildJoinABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from discord import Guild from discord import Guild
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.server import Server from bot_data.model.server import Server
@@ -14,7 +14,7 @@ from bot_data.service.seeder_service import SeederService
class BaseOnGuildJoinEvent(OnGuildJoinABC): class BaseOnGuildJoinEvent(OnGuildJoinABC):
def __init__( def __init__(
self, self,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
server_config: ServerConfigRepositoryABC, server_config: ServerConfigRepositoryABC,

View File

@@ -4,14 +4,15 @@ from typing import Union
import discord import discord
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC from cpl_core.database.context import DatabaseContextABC
from cpl_core.logging import LoggerABC
from cpl_discord.events import OnMemberJoinABC from cpl_discord.events import OnMemberJoinABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from cpl_translation import TranslatePipe from cpl_translation import TranslatePipe
from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.client_utils_abc import ClientUtilsABC
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.abc.permission_service_abc import PermissionServiceABC
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
@@ -20,14 +21,13 @@ from bot_data.model.known_user import KnownUser
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from bot_data.model.user import User from bot_data.model.user import User
from bot_data.model.user_joined_server import UserJoinedServer from bot_data.model.user_joined_server import UserJoinedServer
from bot_core.abc.permission_service_abc import PermissionServiceABC
class BaseOnMemberJoinEvent(OnMemberJoinABC): class BaseOnMemberJoinEvent(OnMemberJoinABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
messenger: MessageServiceABC, messenger: MessageServiceABC,
permissions: PermissionServiceABC, permissions: PermissionServiceABC,
db: DatabaseContextABC, db: DatabaseContextABC,

View File

@@ -4,12 +4,12 @@ from typing import Union
import discord import discord
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC from cpl_core.database.context import DatabaseContextABC
from cpl_core.logging import LoggerABC
from cpl_discord.events import OnMemberRemoveABC from cpl_discord.events import OnMemberRemoveABC
from cpl_translation import TranslatePipe from cpl_translation import TranslatePipe
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC
@@ -20,7 +20,7 @@ class BaseOnMemberRemoveEvent(OnMemberRemoveABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
db: DatabaseContextABC, db: DatabaseContextABC,
message_service: MessageServiceABC, message_service: MessageServiceABC,
users: UserRepositoryABC, users: UserRepositoryABC,

View File

@@ -4,6 +4,7 @@ from cpl_discord.service import DiscordBotServiceABC
from discord import RawReactionActionEvent from discord import RawReactionActionEvent
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from modules.base.helper.base_reaction_handler import BaseReactionHandler from modules.base.helper.base_reaction_handler import BaseReactionHandler
@@ -12,7 +13,7 @@ from modules.base.helper.base_reaction_handler import BaseReactionHandler
class BaseOnRawReactionAddEvent(OnRawReactionAddABC): class BaseOnRawReactionAddEvent(OnRawReactionAddABC):
def __init__( def __init__(
self, self,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
auto_roles: AutoRoleRepositoryABC, auto_roles: AutoRoleRepositoryABC,

View File

@@ -4,6 +4,7 @@ from cpl_discord.service import DiscordBotServiceABC
from discord import RawReactionActionEvent from discord import RawReactionActionEvent
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from modules.base.helper.base_reaction_handler import BaseReactionHandler from modules.base.helper.base_reaction_handler import BaseReactionHandler
@@ -12,7 +13,7 @@ from modules.base.helper.base_reaction_handler import BaseReactionHandler
class BaseOnRawReactionRemoveEvent(OnRawReactionRemoveABC): class BaseOnRawReactionRemoveEvent(OnRawReactionRemoveABC):
def __init__( def __init__(
self, self,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
auto_roles: AutoRoleRepositoryABC, auto_roles: AutoRoleRepositoryABC,

View File

@@ -5,6 +5,7 @@ from cpl_discord.service import DiscordBotServiceABC
from discord import EventStatus from discord import EventStatus
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from modules.base.model.active_event import ActiveEvent from modules.base.model.active_event import ActiveEvent
from modules.base.service.event_service import EventService from modules.base.service.event_service import EventService
@@ -12,7 +13,7 @@ from modules.base.service.event_service import EventService
class BaseOnScheduledEventUpdateEvent(OnScheduledEventUpdateABC): class BaseOnScheduledEventUpdateEvent(OnScheduledEventUpdateABC):
def __init__( def __init__(
self, self,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
events: EventService, events: EventService,
): ):

View File

@@ -8,6 +8,7 @@ from cpl_core.logging import LoggerABC
from cpl_discord.events import OnVoiceStateUpdateABC from cpl_discord.events import OnVoiceStateUpdateABC
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
@@ -25,7 +26,7 @@ class BaseOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
known_users: KnownUserRepositoryABC, known_users: KnownUserRepositoryABC,
users: UserRepositoryABC, users: UserRepositoryABC,

View File

@@ -6,6 +6,7 @@ from cpl_translation import TranslatePipe
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from bot_core.abc.permission_service_abc import PermissionServiceABC from bot_core.abc.permission_service_abc import PermissionServiceABC
@@ -15,7 +16,7 @@ class BaseOnVoiceStateUpdateEventHelpChannel(OnVoiceStateUpdateABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
permissions: PermissionServiceABC, permissions: PermissionServiceABC,
message_service: MessageServiceABC, message_service: MessageServiceABC,

View File

@@ -5,6 +5,7 @@ from cpl_core.logging import LoggerABC
from cpl_discord.events import OnVoiceStateUpdateABC from cpl_discord.events import OnVoiceStateUpdateABC
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC
from modules.base.service.event_service import EventService from modules.base.service.event_service import EventService
@@ -14,7 +15,7 @@ class BaseOnVoiceStateUpdateEventScheduledEventBonus(OnVoiceStateUpdateABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
users: UserRepositoryABC, users: UserRepositoryABC,
events: EventService, events: EventService,

View File

@@ -9,7 +9,7 @@ from cpl_core.database.context import DatabaseContextABC
from cpl_core.logging import LoggerABC from cpl_core.logging import LoggerABC
from cpl_discord.container import Guild from cpl_discord.container import Guild
from cpl_query.extension import List from cpl_query.extension import List
from discord import PrivacyLevel from discord import PrivacyLevel, EventStatus
from discord.scheduled_event import ScheduledEvent as DiscordEvent from discord.scheduled_event import ScheduledEvent as DiscordEvent
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
@@ -99,14 +99,17 @@ class EventService:
async def check_and_create_scheduled_events(self, guild: Guild): async def check_and_create_scheduled_events(self, guild: Guild):
server = self._servers.get_server_by_discord_id(guild.id) server = self._servers.get_server_by_discord_id(guild.id)
scheduled_events_from_db = self._events.get_scheduled_events_by_server_id(server.id) scheduled_events_from_db = self._events.get_scheduled_events_by_server_id(server.id)
self._logger.debug(__name__, f"Checking {scheduled_events_from_db.count()} events for server {guild.id}")
for scheduled_event in scheduled_events_from_db: for scheduled_event in scheduled_events_from_db:
scheduled_event: ScheduledEvent = scheduled_event scheduled_event: ScheduledEvent = scheduled_event
from_guild = List(DiscordEvent, guild.scheduled_events).where( from_guild = List(DiscordEvent, guild.scheduled_events).where(
lambda x: x.name == scheduled_event.name lambda x: x.name == scheduled_event.name
and x.description == scheduled_event.description and x.description == scheduled_event.description
and x.entity_type == scheduled_event.entity_type and x.entity_type == scheduled_event.entity_type
and x.status == EventStatus.scheduled
) )
if from_guild.count() != 0: if from_guild.count() != 0:
self._logger.debug(__name__, f"Event {scheduled_event.name} already exists on discord server")
continue continue
kwargs = {"name": scheduled_event.name, "description": scheduled_event.description} kwargs = {"name": scheduled_event.name, "description": scheduled_event.description}
@@ -119,14 +122,14 @@ class EventService:
scheduled_event.interval, scheduled_event.start_time.replace(tzinfo=ZoneInfo("Europe/Berlin")) scheduled_event.interval, scheduled_event.start_time.replace(tzinfo=ZoneInfo("Europe/Berlin"))
) )
kwargs["start_time"] = start_time kwargs["start_time"] = start_time
scheduled_event.start_time = scheduled_event.start_time.replace(tzinfo=None) scheduled_event.start_time = start_time.replace(tzinfo=None)
if scheduled_event.end_time is not None: if scheduled_event.end_time is not None:
end_time = self._append_interval( end_time = self._append_interval(
scheduled_event.interval, scheduled_event.end_time.replace(tzinfo=ZoneInfo("Europe/Berlin")) scheduled_event.interval, scheduled_event.end_time.replace(tzinfo=ZoneInfo("Europe/Berlin"))
) )
kwargs["end_time"] = end_time kwargs["end_time"] = end_time
scheduled_event.end_time = scheduled_event.end_time.replace(tzinfo=None) scheduled_event.end_time = end_time.replace(tzinfo=None)
kwargs["entity_type"] = scheduled_event.entity_type kwargs["entity_type"] = scheduled_event.entity_type
if scheduled_event.location is not None: if scheduled_event.location is not None:
@@ -135,9 +138,10 @@ class EventService:
kwargs["privacy_level"] = PrivacyLevel.guild_only kwargs["privacy_level"] = PrivacyLevel.guild_only
try: try:
self._logger.debug(__name__, f"Try to create scheduled event for guild {guild.name}") self._logger.trace(__name__, f"Try to create scheduled event for guild {guild.name}")
await guild.create_scheduled_event(**kwargs) await guild.create_scheduled_event(**kwargs)
self._events.update_scheduled_event(scheduled_event) self._events.update_scheduled_event(scheduled_event)
self._db.save_changes() self._db.save_changes()
self._logger.debug(__name__, f"Created scheduled event for guild {guild.name}")
except Exception as e: except Exception as e:
self._logger.error(__name__, f"Watching scheduled events failed", e) self._logger.error(__name__, f"Watching scheduled events failed", e)

View File

@@ -37,7 +37,7 @@ class BirthdayWatcher(TaskABC):
if not self._is_maintenance(): if not self._is_maintenance():
self.watch.start() self.watch.start()
@tasks.loop(time=datetime.time(hour=8, minute=0)) @tasks.loop(time=datetime.time(hour=8, minute=0), reconnect=True)
async def watch(self): async def watch(self):
self._logger.info(__name__, "Watching birthdays") self._logger.info(__name__, "Watching birthdays")
try: try:

View File

@@ -5,9 +5,12 @@ from cpl_translation import TranslatePipe
from discord.ext import tasks from discord.ext import tasks
from bot_core.abc.task_abc import TaskABC 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.logging.task_logger import TaskLogger from bot_core.logging.task_logger import TaskLogger
from bot_core.service.message_service import MessageService from bot_core.service.message_service import MessageService
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.server_config import ServerConfig
from modules.base.service.event_service import EventService from modules.base.service.event_service import EventService
@@ -37,11 +40,18 @@ class ScheduledEventsWatcher(TaskABC):
if not self._is_maintenance(): if not self._is_maintenance():
self.watch.start() self.watch.start()
@tasks.loop(hours=12) @tasks.loop(hours=3, reconnect=True)
async def watch(self): async def watch(self):
self._logger.info(__name__, "Watching scheduled events") self._logger.info(__name__, "Watching scheduled events")
try: try:
for guild in self._bot.guilds: for guild in self._bot.guilds:
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
if not FeatureFlagsSettings.get_flag_from_dict(
settings.feature_flags, FeatureFlagsEnum.scheduled_events
):
self._logger.debug(__name__, f"Skipping scheduled event check for {guild.id}. Feature is disabled.")
continue
await self._events.check_and_create_scheduled_events(guild) await self._events.check_and_create_scheduled_events(guild)
except Exception as e: except Exception as e:
self._logger.error(__name__, f"Watching scheduled events failed", e) self._logger.error(__name__, f"Watching scheduled events failed", e)

View File

@@ -10,6 +10,7 @@ from discord import guild
from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.abc.message_service_abc import MessageServiceABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.logging.event_logger import EventLogger
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from bot_data.model.technician_config import TechnicianConfig from bot_data.model.technician_config import TechnicianConfig
@@ -18,7 +19,7 @@ class BootLogOnReadyEvent(OnReadyABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
message_service: MessageServiceABC, message_service: MessageServiceABC,
translate: TranslatePipe, translate: TranslatePipe,

View File

@@ -1,8 +1,8 @@
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.logging import LoggerABC
from cpl_discord.events import OnReadyABC from cpl_discord.events import OnReadyABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from bot_core.logging.event_logger import EventLogger
from bot_core.service.config_service import ConfigService from bot_core.service.config_service import ConfigService
from bot_core.service.data_integrity_service import DataIntegrityService from bot_core.service.data_integrity_service import DataIntegrityService
from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC
@@ -12,7 +12,7 @@ class ConfigOnReadyEvent(OnReadyABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
servers: ServerRepositoryABC, servers: ServerRepositoryABC,
config_service: ConfigService, config_service: ConfigService,

View File

@@ -5,13 +5,14 @@ from cpl_discord.events import OnMemberJoinABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_core.logging.message_logger import MessageLogger from bot_core.logging.message_logger import MessageLogger
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from modules.level.service.level_service import LevelService from modules.level.service.level_service import LevelService
class LevelOnMemberJoinEvent(OnMemberJoinABC): class LevelOnMemberJoinEvent(OnMemberJoinABC):
def __init__(self, config: ConfigurationABC, logger: MessageLogger, level: LevelService): def __init__(self, config: ConfigurationABC, logger: EventLogger, level: LevelService):
OnMemberJoinABC.__init__(self) OnMemberJoinABC.__init__(self)
self._config = config self._config = config
self._logger = logger self._logger = logger

View File

@@ -7,6 +7,7 @@ from discord import RawReactionActionEvent
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from modules.level.service.level_service import LevelService from modules.level.service.level_service import LevelService
@@ -15,7 +16,7 @@ class LevelOnRawReactionAddEvent(OnRawReactionAddABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
level: LevelService, level: LevelService,
): ):

View File

@@ -7,6 +7,7 @@ from discord import RawReactionActionEvent
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from modules.level.service.level_service import LevelService from modules.level.service.level_service import LevelService
@@ -15,7 +16,7 @@ class LevelOnRawReactionRemoveEvent(OnRawReactionRemoveABC):
def __init__( def __init__(
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: LoggerABC, logger: EventLogger,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
level: LevelService, level: LevelService,
): ):

View File

@@ -6,12 +6,13 @@ from cpl_discord.events import OnVoiceStateUpdateABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.helper.event_checks import EventChecks from bot_core.helper.event_checks import EventChecks
from bot_core.logging.event_logger import EventLogger
from bot_data.model.server_config import ServerConfig from bot_data.model.server_config import ServerConfig
from modules.level.service.level_service import LevelService from modules.level.service.level_service import LevelService
class LevelOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): class LevelOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC):
def __init__(self, config: ConfigurationABC, logger: LoggerABC, level: LevelService): def __init__(self, config: ConfigurationABC, logger: EventLogger, level: LevelService):
OnVoiceStateUpdateABC.__init__(self) OnVoiceStateUpdateABC.__init__(self)
self._config = config self._config = config
self._logger = logger self._logger = logger

View File

@@ -17,6 +17,6 @@ class SteamSpecialOffersModule(ModuleABC):
pass pass
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
services.add_singleton(TaskABC, SteamOfferWatcher) services.add_transient(TaskABC, SteamOfferWatcher)
# commands # commands
# events # events

View File

@@ -187,7 +187,7 @@ class SteamOfferWatcher(TaskABC):
self._logger.trace(__name__, "Finished watching") self._logger.trace(__name__, "Finished watching")
return offers_for_notifications return offers_for_notifications
@tasks.loop(hours=4) @tasks.loop(hours=4, reconnect=True)
async def watch(self): async def watch(self):
self._logger.info(__name__, "Watching steam special offers") self._logger.info(__name__, "Watching steam special offers")
try: try:

View File

@@ -36,6 +36,8 @@ export interface User extends DataWithHistory {
userWarningCount?: number; userWarningCount?: number;
userWarnings?: UserWarning[]; userWarnings?: UserWarning[];
profilePictureURL?: string;
} }
export interface UserFilter { export interface UserFilter {

View File

@@ -406,6 +406,7 @@ export class Queries {
joinedOn joinedOn
leavedOn leavedOn
} }
profilePictureURL
createdAt createdAt
modifiedAt modifiedAt

View File

@@ -40,6 +40,7 @@ import { TabViewModule } from "primeng/tabview";
import { RadioButtonModule } from "primeng/radiobutton"; import { RadioButtonModule } from "primeng/radiobutton";
import { InputTextareaModule } from "primeng/inputtextarea"; import { InputTextareaModule } from "primeng/inputtextarea";
import { InputMaskModule } from "primeng/inputmask"; import { InputMaskModule } from "primeng/inputmask";
import { KnobModule } from "primeng/knob";
const PrimeNGModules = [ const PrimeNGModules = [
@@ -73,7 +74,8 @@ const PrimeNGModules = [
TabViewModule, TabViewModule,
RadioButtonModule, RadioButtonModule,
InputTextareaModule, InputTextareaModule,
InputMaskModule InputMaskModule,
KnobModule
]; ];
@NgModule({ @NgModule({

View File

@@ -2,14 +2,17 @@
{{'view.server.profile.header' | translate}} {{'view.server.profile.header' | translate}}
</h1> </h1>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content-header">
<h2>
{{user.name}}
</h2>
</div>
<div class="content"> <div class="content">
<div class="content-row"> <div class="content-row">
<div class="content-column">
<div class="logo">
<img *ngIf="user ? user.profilePictureURL : ''" [src]="user ? user.profilePictureURL : ''">
</div>
</div>
<div class="content">
<div class="content-column">
<h1>{{user.name}}</h1>
</div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.id' | translate}}:</div> <div class="content-data-name">{{'common.id' | translate}}:</div>
<div class="content-data-value">{{user.id}}</div> <div class="content-data-value">{{user.id}}</div>
@@ -18,103 +21,76 @@
<div class="content-data-name">{{'common.discord_id' | translate}}:</div> <div class="content-data-name">{{'common.discord_id' | translate}}:</div>
<div class="content-data-value">{{user.discordId}}</div> <div class="content-data-value">{{user.discordId}}</div>
</div> </div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'view.server.profile.name' | translate}}:</div>
<div class="content-data-value">{{user.name}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'view.server.profile.xp' | translate}}:</div>
<div *ngIf="!isEditing" class="content-data-value">{{user.xp}}</div>
<div *ngIf="isModerator && isEditing" class="content-data-value"><input class="table-edit-input" pInputText
min="0" type="number"
[(ngModel)]="user.xp"></div>
</div>
</div>
<div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.message_count' | translate}}:</div> <div class="content-data-name">{{'view.server.profile.message_count' | translate}}:</div>
<div class="content-data-value">{{user.messageCount}}</div> <div class="content-data-value">{{user.messageCount}}</div>
</div> </div>
</div>
<div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.reaction_count' | translate}}:</div> <div class="content-data-name">{{'view.server.profile.reaction_count' | translate}}:</div>
<div class="content-data-value">{{user.reactionCount}}</div> <div class="content-data-value">{{user.reactionCount}}</div>
</div> </div>
</div>
<div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.birthday' | translate}}:</div> <div class="content-data-name">{{'view.server.profile.birthday' | translate}}:</div>
<div *ngIf="!isEditing" class="content-data-value">{{user.birthday}}</div> <div *ngIf="!isEditing" class="content-data-value">{{user.birthday}}</div>
<div *ngIf="isEditing" class="content-data-value"> <div *ngIf="isEditing" class="content-data-value">
<p-calendar [(ngModel)]="user.birthday" dateFormat="dd.mm.yy" [showIcon]="true"></p-calendar> <p-calendar [(ngModel)]="user.birthday" dateFormat="dd.mm.yy"
[showIcon]="true"></p-calendar>
</div> </div>
</div> </div>
</div> <div class="content-divider"></div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'common.ontime' | translate}}:</div>
<div class="content-data-value">{{user.ontime}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'common.game_ontime' | translate}}:</div>
<div class="content-data-value">{{user.gameOntime}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'common.activity' | translate}}:</div>
<div class="content-data-value">{{user.activityScore}}</div>
</div>
</div>
<div class="content-row">
<div class="content-column">
<div class="content-data-name">{{'view.server.profile.level' | translate}}:</div>
<div *ngIf="!isEditing" class="content-data-value">{{user.level?.name}}</div>
<div *ngIf="isModerator && isEditing" class="content-data-value">
<p-dropdown [options]="levels" [(ngModel)]="user.level" dataKey="id"
placeholder="{{'common.level' | translate}}">
</p-dropdown>
</div>
</div>
</div>
<div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.left_server' | translate}}:</div> <div class="content-data-name">{{'view.server.profile.left_server' | translate}}:</div>
<div class="content-data-value">{{user.leftServer | bool}}</div> <div class="content-data-value">{{user.leftServer | bool}}</div>
</div> </div>
</div>
<div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.created_at' | translate}}:</div> <div class="content-data-name">{{'common.created_at' | translate}}:</div>
<div class="content-data-value">{{user.createdAt | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{user.createdAt | date:'dd.MM.yyyy HH:mm:ss'}}</div>
</div> </div>
</div>
<div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.modified_at' | translate}}:</div> <div class="content-data-name">{{'common.modified_at' | translate}}:</div>
<div class="content-data-value">{{user.modifiedAt | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{user.modifiedAt | date:'dd.MM.yyyy HH:mm:ss'}}</div>
</div> </div>
</div> </div>
<div class="content">
<div class="content-column">
<div class="content-data-name" style="flex-direction: column; justify-content: start;">
<p-knob valueTemplate="{value} {{'view.server.profile.xp' | translate}}" [(ngModel)]="user.xp" [size]="150"
[strokeWidth]="10"
[max]="maxXp" valueColor="SlateGray" rangeColor="MediumTurquoise"
[readonly]="isModerator && !isEditing"></p-knob>
</div>
<div class="content-data-value" style="flex-direction: column; justify-content: start;">
<p-knob valueTemplate="Lvl {value}" [(ngModel)]="activeLevelIndex"
[size]="150"
[strokeWidth]="10"
[min]="1"
[max]="levels ? levels.length : 0" valueColor="SlateGray" rangeColor="MediumTurquoise"
[readonly]="isModerator && !isEditing"></p-knob>
<div *ngIf="user.level">
{{user.level.name}}
</div>
</div>
</div>
<div class="content-divider"></div>
<div class="content-column">
<div class="content-data-name">{{'common.ontime' | translate}}:</div>
<div class="content-data-value">{{user.ontime}}</div>
</div>
<div class="content-column">
<div class="content-data-name">{{'common.game_ontime' | translate}}:</div>
<div class="content-data-value">{{user.gameOntime}}</div>
</div>
<div class="content-column">
<div class="content-data-name">{{'common.activity' | translate}}:</div>
<div class="content-data-value">{{user.activityScore}}</div>
</div>
</div>
</div>
</div>
<div class="content">
<div> <div>
<div class="content-divider"></div> <div class="content-divider"></div>
<p-table #dt [value]="(user.userWarnings ?? [])" [responsive]="true" responsiveLayout="stack" <p-table #dt [value]="(user.userWarnings ?? [])" [responsive]="true" responsiveLayout="stack"
@@ -199,7 +175,8 @@
<button *ngIf="!editing" pButton type="button" class="btn danger-icon-btn" icon="pi pi-trash" <button *ngIf="!editing" pButton type="button" class="btn danger-icon-btn" icon="pi pi-trash"
(click)="deleteUserWarning(ri)"></button> (click)="deleteUserWarning(ri)"></button>
<button *ngIf="editing" pButton type="button" pSaveEditableRow class="btn icon-btn" icon="pi pi-check" <button *ngIf="editing" pButton type="button" pSaveEditableRow class="btn icon-btn"
icon="pi pi-check"
(click)="editSaveUserWarning(value, ri)"></button> (click)="editSaveUserWarning(value, ri)"></button>
<button *ngIf="editing" pButton type="button" pCancelEditableRow class="btn danger-icon-btn" <button *ngIf="editing" pButton type="button" pCancelEditableRow class="btn danger-icon-btn"
icon="pi pi-times" icon="pi pi-times"

View File

@@ -0,0 +1,6 @@
.logo {
img {
width: 12.5vw;
border-radius: 50%;
}
}

View File

@@ -15,10 +15,10 @@ import { catchError, takeUntil } from "rxjs/operators";
import { Table } from "primeng/table"; import { Table } from "primeng/table";
import { UpdateUserMutationResult } from "../../../../models/graphql/result.model"; import { UpdateUserMutationResult } from "../../../../models/graphql/result.model";
import { Mutations } from "../../../../models/graphql/mutations.model"; import { Mutations } from "../../../../models/graphql/mutations.model";
import { MenuItem } from "primeng/api";
import { UserWarning } from "../../../../models/data/user_warning.model"; import { UserWarning } from "../../../../models/data/user_warning.model";
import moment from "moment"; import moment from "moment";
import { SidebarService } from "../../../../services/sidebar/sidebar.service"; import { SidebarService } from "../../../../services/sidebar/sidebar.service";
import { Level } from "../../../../models/data/level.model";
@Component({ @Component({
selector: "app-profile", selector: "app-profile",
@@ -28,7 +28,7 @@ import { SidebarService } from "../../../../services/sidebar/sidebar.service";
export class ProfileComponent implements OnInit, OnDestroy { export class ProfileComponent implements OnInit, OnDestroy {
user: User = { createdAt: "", modifiedAt: "" }; user: User = { createdAt: "", modifiedAt: "" };
levels!: MenuItem[]; levels!: { label: string, value: Level }[];
private server: Server = {}; private server: Server = {};
private author?: UserDTO; private author?: UserDTO;
private clonedUserWarnings: UserWarning[] = []; private clonedUserWarnings: UserWarning[] = [];
@@ -36,6 +36,21 @@ export class ProfileComponent implements OnInit, OnDestroy {
public isEditing: boolean = false; public isEditing: boolean = false;
public isModerator: boolean = false; public isModerator: boolean = false;
public hasTechnicianAccess: boolean = false; public hasTechnicianAccess: boolean = false;
public maxXp: number = 0;
private _activeLevelIndex: number = 0;
public get activeLevelIndex(): number {
return this._activeLevelIndex;
}
public set activeLevelIndex(value: number) {
if (value < 1) {
value = 1;
}
this._activeLevelIndex = value;
this.user.level = this.levels.map(x => x.value)[value - 1];
}
private unsubscriber = new Subject<void>(); private unsubscriber = new Subject<void>();
@@ -48,7 +63,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
private toast: ToastService, private toast: ToastService,
private translate: TranslateService, private translate: TranslateService,
private toastService: ToastService, private toastService: ToastService,
private sidebarService: SidebarService, private sidebarService: SidebarService
) { ) {
} }
@@ -74,7 +89,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
} }
).subscribe(data => { ).subscribe(data => {
this.levels = data.levels.map(level => { this.levels = data.levels.map(level => {
return { label: level.name, value: level }; return { label: level.name ?? "", value: level };
}); });
}); });
@@ -100,6 +115,11 @@ export class ProfileComponent implements OnInit, OnDestroy {
this.router.navigate([`/server/${server.id}`]); this.router.navigate([`/server/${server.id}`]);
} }
this.user = users.users[0]; this.user = users.users[0];
const minXps = this.levels.reverse().map(x => x.value.minXp ?? 0);
this.maxXp = minXps.filter(x => this.user.xp && x > this.user.xp)[0] ?? this.user.xp;
if (this.user.level) {
this.activeLevelIndex = this.levels.map(l => l.value.id).indexOf(this.user.level.id) + 1;
}
this.data.query<UserWarningQuery>(Queries.userProfileWarnings, { this.data.query<UserWarningQuery>(Queries.userProfileWarnings, {
serverId: this.server.id, serverId: this.server.id,
@@ -128,7 +148,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
this.data.mutation<UpdateUserMutationResult>(Mutations.updateUser, { this.data.mutation<UpdateUserMutationResult>(Mutations.updateUser, {
id: this.user.id, id: this.user.id,
xp: this.user.xp, xp: this.user.xp,
birthday: moment(this.user.birthday).format("DD.MM.YYYY"), birthday: moment(this.user.birthday, "DD.MM.YYYY").format("DD.MM.YYYY"),
levelId: this.user.level?.id, levelId: this.user.level?.id,
userWarnings: this.user.userWarnings?.map(userWarning => { userWarnings: this.user.userWarnings?.map(userWarning => {
return { return {

View File

@@ -541,6 +541,7 @@
}, },
"left_server": "Hat Server verlassen", "left_server": "Hat Server verlassen",
"level": "Level", "level": "Level",
"lvl": "Lvl",
"message_count": "Anzahl Nachrichten", "message_count": "Anzahl Nachrichten",
"minecraft_id": "Minecraft Id", "minecraft_id": "Minecraft Id",
"name": "Name", "name": "Name",

View File

@@ -541,6 +541,7 @@
}, },
"left_server": "Leaved server", "left_server": "Leaved server",
"level": "Level", "level": "Level",
"lvl": "Lvl",
"message_count": "Message count", "message_count": "Message count",
"minecraft_id": "Minecraft Id", "minecraft_id": "Minecraft Id",
"name": "Name", "name": "Name",

View File

@@ -177,6 +177,7 @@ header {
flex: 1; flex: 1;
margin: 5px 0; margin: 5px 0;
gap: 5px; gap: 5px;
}
.content-column { .content-column {
display: flex; display: flex;
@@ -211,7 +212,6 @@ header {
font-size: 18px; font-size: 18px;
} }
}
.content-divider { .content-divider {
margin: 10px 0; margin: 10px 0;

View File

@@ -814,4 +814,22 @@
box-shadow: none !important; box-shadow: none !important;
} }
} }
p-knob {
.p-knob {
svg {
.p-knob-value {
stroke: $primaryHeaderColor !important;
}
.p-knob-range {
stroke: $secondaryBackgroundColor !important;
}
.p-knob-text {
font-size: 1rem !important;
}
}
}
}
} }