Compare commits
16 Commits
1.2.5
...
dd6b609094
Author | SHA1 | Date | |
---|---|---|---|
dd6b609094 | |||
3810dec927 | |||
a87380f6f8 | |||
98ac7835b6 | |||
0a76068604 | |||
f9caf59180 | |||
284318bb10 | |||
6130cac6fe | |||
3a64c51600 | |||
90fce5a79a | |||
d448ad7707 | |||
19791ff9d8 | |||
3cba8de675 | |||
b7ff070676 | |||
c88e07d743 | |||
f5b978b231 |
@@ -6,116 +6,52 @@ on:
|
|||||||
- dev
|
- dev
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-build:
|
on-push-deploy_sh-edraft:
|
||||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
||||||
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
|
container: catthehacker/ubuntu:act-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Shutdown stack
|
- name: Setup Python 3.10
|
||||||
run: docker stack rm sdb_dev
|
uses: actions/setup-python@v3
|
||||||
|
with:
|
||||||
|
python-version: "3.10.12"
|
||||||
|
- run: python -v
|
||||||
|
|
||||||
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:
|
|
||||||
- name: Setup docker
|
- name: Setup docker
|
||||||
uses: https://github.com/papodaca/install-docker-action@main
|
uses: https://github.com/papodaca/install-docker-action@main
|
||||||
- run: docker -v
|
- run: docker -v
|
||||||
|
|
||||||
- name: Clone Repository
|
- name: Clone Repository
|
||||||
uses: https://github.com/actions/checkout@v3
|
uses: https://github.com/actions/checkout@v3
|
||||||
with:
|
|
||||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
- name: Shutdown stack
|
||||||
submodules: true
|
run: docker stack rm kdb_staging
|
||||||
|
|
||||||
- name: Prepare bot build
|
- name: Prepare bot build
|
||||||
run: |
|
run: |
|
||||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
cd kdb-bot
|
||||||
cd bot
|
pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
||||||
cpl i
|
cpl i
|
||||||
|
|
||||||
- name: Build docker bot
|
- name: Build docker bot
|
||||||
run: |
|
run: |
|
||||||
cd bot
|
cd kdb-bot
|
||||||
docker image prune -f
|
docker image prune -f
|
||||||
cpl build
|
cpl docker-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
|
||||||
|
|
||||||
- name: Prepare web build
|
- name: Prepare web build
|
||||||
run: |
|
run: |
|
||||||
cd web
|
cd kdb-web
|
||||||
npm install -g ts-node
|
npm install -g ts-node
|
||||||
npm ci
|
npm i
|
||||||
|
|
||||||
- name: Build docker web
|
- name: Build docker web
|
||||||
run: |
|
run: |
|
||||||
cd web
|
cd kdb-web
|
||||||
docker image prune -f
|
docker image prune -f
|
||||||
cp src/favicon.dev.ico src/favicon.ico
|
npm run docker-build
|
||||||
npm run build
|
|
||||||
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
|
|
||||||
run: |
|
|
||||||
cd bot/docker
|
|
||||||
chmod +x ./set-docker-compose-image-version.sh
|
|
||||||
./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
|
||||||
@@ -124,6 +60,6 @@ jobs:
|
|||||||
portainer-username: "gitea_job"
|
portainer-username: "gitea_job"
|
||||||
portainer-password: "${{ secrets.docker_job }}"
|
portainer-password: "${{ secrets.docker_job }}"
|
||||||
portainer-endpoint: 2
|
portainer-endpoint: 2
|
||||||
name: sdb_dev
|
name: kdb_staging
|
||||||
file: bot/docker/docker-compose.dev.yml
|
file: ./docker-compose.staging.yml
|
||||||
variables: '{}'
|
variables: '{}'
|
||||||
|
@@ -1,120 +1,57 @@
|
|||||||
name: Deploy prod on push
|
name: Deploy dev on push
|
||||||
run-name: Deploy prod on push
|
run-name: Deploy dev on push
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-build:
|
on-push-deploy_sh-edraft:
|
||||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
||||||
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
|
container: catthehacker/ubuntu:act-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Shutdown stack
|
- name: Setup Python 3.10
|
||||||
run: docker stack rm sdb_prod
|
uses: actions/setup-python@v3
|
||||||
|
with:
|
||||||
|
python-version: "3.10.12"
|
||||||
|
- run: python -v
|
||||||
|
|
||||||
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:
|
|
||||||
- name: Setup docker
|
- name: Setup docker
|
||||||
uses: https://github.com/papodaca/install-docker-action@main
|
uses: https://github.com/papodaca/install-docker-action@main
|
||||||
- run: docker -v
|
- run: docker -v
|
||||||
|
|
||||||
- name: Clone Repository
|
- name: Clone Repository
|
||||||
uses: https://github.com/actions/checkout@v3
|
uses: https://github.com/actions/checkout@v3
|
||||||
with:
|
|
||||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
- name: Shutdown stack
|
||||||
submodules: true
|
run: docker stack rm kdb_prod
|
||||||
|
|
||||||
- name: Prepare bot build
|
- name: Prepare bot build
|
||||||
run: |
|
run: |
|
||||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
cd kdb-bot
|
||||||
cd bot
|
pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
||||||
cpl i
|
cpl i
|
||||||
|
|
||||||
- name: Build docker bot
|
- name: Build docker bot
|
||||||
run: |
|
run: |
|
||||||
cd bot
|
cd kdb-bot
|
||||||
docker image prune -f
|
docker image prune -f
|
||||||
cpl build
|
cpl docker-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
|
||||||
|
|
||||||
- name: Prepare web build
|
- name: Prepare web build
|
||||||
run: |
|
run: |
|
||||||
cd web
|
cd kdb-web
|
||||||
npm install -g ts-node
|
npm install -g ts-node
|
||||||
npm ci
|
npm i
|
||||||
|
|
||||||
- name: Build docker web
|
- name: Build docker web
|
||||||
run: |
|
run: |
|
||||||
cd web
|
cd kdb-web
|
||||||
docker image prune -f
|
docker image prune -f
|
||||||
npm run build
|
npm run docker-build
|
||||||
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
|
|
||||||
run: |
|
|
||||||
cd bot/docker
|
|
||||||
chmod +x ./set-docker-compose-image-version.sh
|
|
||||||
./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
|
||||||
@@ -123,6 +60,6 @@ jobs:
|
|||||||
portainer-username: "gitea_job"
|
portainer-username: "gitea_job"
|
||||||
portainer-password: "${{ secrets.docker_job }}"
|
portainer-password: "${{ secrets.docker_job }}"
|
||||||
portainer-endpoint: 2
|
portainer-endpoint: 2
|
||||||
name: sdb_prod
|
name: kdb_prod
|
||||||
file: bot/docker/docker-compose.yml
|
file: ./docker-compose.yml
|
||||||
variables: '{}'
|
variables: '{}'
|
||||||
|
@@ -1,129 +0,0 @@
|
|||||||
name: Deploy staging on push
|
|
||||||
run-name: Deploy staging on push
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- staging
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pre-build:
|
|
||||||
runs-on: [ dobby.sh-edraft.de, ubuntu-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:
|
|
||||||
- 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: |
|
|
||||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
|
||||||
cd bot
|
|
||||||
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
|
|
||||||
uses: https://github.com/actions/setup-node@v3
|
|
||||||
|
|
||||||
- name: Prepare web build
|
|
||||||
run: |
|
|
||||||
cd web
|
|
||||||
npm install -g ts-node
|
|
||||||
npm ci
|
|
||||||
|
|
||||||
- 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 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
|
|
||||||
run: |
|
|
||||||
cd bot/docker
|
|
||||||
chmod +x ./set-docker-compose-image-version.sh
|
|
||||||
./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
|
|
||||||
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: '{}'
|
|
@@ -14,14 +14,14 @@
|
|||||||
"config": "src/modules/config/config.json",
|
"config": "src/modules/config/config.json",
|
||||||
"database": "src/modules/database/database.json",
|
"database": "src/modules/database/database.json",
|
||||||
"level": "src/modules/level/level.json",
|
"level": "src/modules/level/level.json",
|
||||||
|
"permission": "src/modules/permission/permission.json",
|
||||||
"technician": "src/modules/technician/technician.json",
|
"technician": "src/modules/technician/technician.json",
|
||||||
"short-role-name": "src/modules/short_role_name/short-role-name.json",
|
"short-role-name": "src/modules/short_role_name/short-role-name.json",
|
||||||
"special-offers": "src/modules/special_offers/special-offers.json",
|
"special-offers": "src/modules/special_offers/special-offers.json",
|
||||||
"checks": "tools/checks/checks.json",
|
"checks": "tools/checks/checks.json",
|
||||||
"get-version": "tools/get_version/get-version.json",
|
"get-version": "tools/get_version/get-version.json",
|
||||||
"post-build": "tools/post_build/post-build.json",
|
"post-build": "tools/post_build/post-build.json",
|
||||||
"set-version": "tools/set_version/set-version.json",
|
"set-version": "tools/set_version/set-version.json"
|
||||||
"migration-to-sql": "tools/migration_to_sql/migration-to-sql.json"
|
|
||||||
},
|
},
|
||||||
"Scripts": {
|
"Scripts": {
|
||||||
"format": "black ./",
|
"format": "black ./",
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
"pre-build": "cpl set-version $ARGS; black ./;",
|
"pre-build": "cpl set-version $ARGS; black ./;",
|
||||||
"post-build": "cpl run post-build --dev; black ./;",
|
"post-build": "cpl run post-build --dev; black ./;",
|
||||||
"pre-prod": "cpl build",
|
"pre-prod": "cpl build",
|
||||||
"prod": "export SDB_ENVIRONMENT=production; export SDB_NAME=SDB-Prod; cpl start;",
|
"prod": "export KDB_ENVIRONMENT=production; export KDB_NAME=KDB-Prod; cpl start;",
|
||||||
"pre-stage": "cpl build",
|
"pre-stage": "cpl build",
|
||||||
"stage": "export SDB_ENVIRONMENT=staging; export SDB_NAME=SDB-Stage; cpl start;",
|
"stage": "export KDB_ENVIRONMENT=staging; export KDB_NAME=KDB-Stage; cpl start;",
|
||||||
"pre-dev": "cpl build",
|
"pre-dev": "cpl build",
|
||||||
"dev": "export SDB_ENVIRONMENT=development; export SDB_NAME=SDB-Dev; cpl start;",
|
"dev": "export KDB_ENVIRONMENT=development; export KDB_NAME=KDB-Dev; cpl start;",
|
||||||
"docker-build": "cpl build $ARGS; docker build -t sh-edraft.de/sdb-bot:$(cpl gv) .;",
|
"docker-build": "cpl build $ARGS; docker build -t sh-edraft.de/kdb-bot:$(cpl gv) .;",
|
||||||
"dc-up": "docker-compose up -d",
|
"dc-up": "docker-compose up -d",
|
||||||
"dc-down": "docker-compose down",
|
"dc-down": "docker-compose down",
|
||||||
"docker": "cpl dc-down; cpl docker-build; cpl dc-up;"
|
"docker": "cpl dc-down; cpl docker-build; cpl dc-up;"
|
||||||
|
Submodule bot/docker deleted from 36ed43055d
@@ -2,7 +2,7 @@
|
|||||||
FROM python:3.10.4-alpine
|
FROM python:3.10.4-alpine
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY ./dist/bot/build/bot/ .
|
COPY ./dist/bot/build/kdb-bot/ .
|
||||||
COPY ./dist/bot/build/requirements.txt .
|
COPY ./dist/bot/build/requirements.txt .
|
||||||
|
|
||||||
RUN python -m pip install --upgrade pip
|
RUN python -m pip install --upgrade pip
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -11,7 +11,6 @@ from bot_api.api_thread import ApiThread
|
|||||||
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_enum import FeatureFlagsEnum
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
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
|
from bot_core.service.data_integrity_service import DataIntegrityService
|
||||||
|
|
||||||
|
|
||||||
@@ -24,17 +23,25 @@ class Application(DiscordBotApplicationABC):
|
|||||||
|
|
||||||
# cpl-core
|
# cpl-core
|
||||||
self._logger: LoggerABC = services.get_service(LoggerABC)
|
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
|
# cpl-discord
|
||||||
self._bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC)
|
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
|
# cpl-translation
|
||||||
self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC)
|
self._translation: TranslationServiceABC = services.get_service(
|
||||||
|
TranslationServiceABC
|
||||||
|
)
|
||||||
self._t: TranslatePipe = services.get_service(TranslatePipe)
|
self._t: TranslatePipe = services.get_service(TranslatePipe)
|
||||||
# internal stuff
|
# internal stuff
|
||||||
self._tasks = services.get_services(TaskABC)
|
self._tasks = services.get_services(TaskABC)
|
||||||
|
|
||||||
self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings)
|
self._feature_flags: FeatureFlagsSettings = config.get_configuration(
|
||||||
|
FeatureFlagsSettings
|
||||||
|
)
|
||||||
|
|
||||||
# api
|
# api
|
||||||
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
||||||
@@ -43,7 +50,9 @@ class Application(DiscordBotApplicationABC):
|
|||||||
self._is_stopping = False
|
self._is_stopping = False
|
||||||
|
|
||||||
async def configure(self):
|
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):
|
async def main(self):
|
||||||
try:
|
try:
|
||||||
@@ -59,9 +68,8 @@ class Application(DiscordBotApplicationABC):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}")
|
self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}")
|
||||||
if not self._config.get_configuration(MAINTENANCE):
|
for task in self._tasks:
|
||||||
for task in self._tasks:
|
await self._bot.add_cog(task)
|
||||||
await self._bot.add_cog(task)
|
|
||||||
|
|
||||||
await self._bot.start_async()
|
await self._bot.start_async()
|
||||||
await self._bot.stop_async()
|
await self._bot.stop_async()
|
||||||
@@ -87,4 +95,8 @@ class Application(DiscordBotApplicationABC):
|
|||||||
Console.write_line()
|
Console.write_line()
|
||||||
|
|
||||||
def is_restart(self):
|
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
|
||||||
|
)
|
||||||
|
0
bot/src/bot/bot
Executable file → Normal file
0
bot/src/bot/bot
Executable file → Normal file
@@ -4,7 +4,7 @@
|
|||||||
"Version": {
|
"Version": {
|
||||||
"Major": "1",
|
"Major": "1",
|
||||||
"Minor": "2",
|
"Minor": "2",
|
||||||
"Micro": "5"
|
"Micro": "0"
|
||||||
},
|
},
|
||||||
"Author": "Sven Heidemann",
|
"Author": "Sven Heidemann",
|
||||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
"LicenseName": "MIT",
|
"LicenseName": "MIT",
|
||||||
"LicenseDescription": "MIT, see LICENSE for more details.",
|
"LicenseDescription": "MIT, see LICENSE for more details.",
|
||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
|
"cpl-core==2023.10.0",
|
||||||
"cpl-translation==2023.4.0.post1",
|
"cpl-translation==2023.4.0.post1",
|
||||||
"cpl-query==2023.10.0",
|
"cpl-query==2023.10.0",
|
||||||
"cpl-discord==2023.10.0.post1",
|
"cpl-discord==2023.10.0.post1",
|
||||||
@@ -30,16 +31,11 @@
|
|||||||
"icmplib==3.0.4",
|
"icmplib==3.0.4",
|
||||||
"ariadne==0.20.1",
|
"ariadne==0.20.1",
|
||||||
"cryptography==41.0.4",
|
"cryptography==41.0.4",
|
||||||
"discord==2.3.2",
|
"discord==2.3.2"
|
||||||
"bs4==0.0.1",
|
|
||||||
"lxml==4.9.3",
|
|
||||||
"python-valve==0.2.1",
|
|
||||||
"cpl-core==2023.10.2"
|
|
||||||
],
|
],
|
||||||
"DevDependencies": [
|
"DevDependencies": [
|
||||||
"cpl-cli==2023.4.0.post3",
|
"cpl-cli==2023.4.0.post3",
|
||||||
"pygount==1.6.1",
|
"pygount==1.6.1"
|
||||||
"black==23.10.1"
|
|
||||||
],
|
],
|
||||||
"PythonVersion": ">=3.10.4",
|
"PythonVersion": ">=3.10.4",
|
||||||
"PythonPath": {},
|
"PythonPath": {},
|
||||||
@@ -71,6 +67,7 @@
|
|||||||
"../modules/config/config.json",
|
"../modules/config/config.json",
|
||||||
"../modules/database/database.json",
|
"../modules/database/database.json",
|
||||||
"../modules/level/level.json",
|
"../modules/level/level.json",
|
||||||
|
"../modules/permission/permission.json",
|
||||||
"../modules/short_role_name/short-role-name.json",
|
"../modules/short_role_name/short-role-name.json",
|
||||||
"../modules/special_offers/special-offers.json",
|
"../modules/special_offers/special-offers.json",
|
||||||
"../modules/technician/technician.json"
|
"../modules/technician/technician.json"
|
||||||
|
Submodule bot/src/bot/config deleted from eeebd13f80
@@ -15,7 +15,7 @@ __title__ = "bot.extension"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
import os
|
|
||||||
import shutil
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from cpl_core.application.application_extension_abc import ApplicationExtensionABC
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
|
|
||||||
class CleanLogsExtension(ApplicationExtensionABC):
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
|
||||||
(
|
|
||||||
List(str, os.listdir("logs/"))
|
|
||||||
.where(lambda x: os.path.isdir(f"logs/{x}"))
|
|
||||||
.order_by()
|
|
||||||
.where(lambda x: (datetime.now() - datetime.strptime(x, "%Y-%m-%d")).days >= 7)
|
|
||||||
.for_each(lambda x: shutil.rmtree(f"logs/{x}"))
|
|
||||||
)
|
|
@@ -13,4 +13,6 @@ class InitBotExtension(ApplicationExtensionABC):
|
|||||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||||
settings = config.get_configuration(TechnicianConfig)
|
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
|
||||||
|
)
|
||||||
|
@@ -6,11 +6,10 @@ from cpl_core.application import ApplicationBuilder
|
|||||||
from cpl_core.console import Console
|
from cpl_core.console import Console
|
||||||
|
|
||||||
from bot.application import Application
|
from bot.application import Application
|
||||||
from bot.extension.clean_logs_extension import CleanLogsExtension
|
|
||||||
from bot.extension.init_bot_extension import InitBotExtension
|
from bot.extension.init_bot_extension import InitBotExtension
|
||||||
from bot.startup import Startup
|
from bot.startup import Startup
|
||||||
from bot.startup_discord_extension import StartupDiscordExtension
|
from bot.startup_discord_extension import StartupDiscordExtension
|
||||||
from bot_data.startup_migration_extension import StartupMigrationExtension
|
from bot.startup_migration_extension import StartupMigrationExtension
|
||||||
from bot.startup_module_extension import StartupModuleExtension
|
from bot.startup_module_extension import StartupModuleExtension
|
||||||
from bot.startup_settings_extension import StartupSettingsExtension
|
from bot.startup_settings_extension import StartupSettingsExtension
|
||||||
from bot_api.app_api_extension import AppApiExtension
|
from bot_api.app_api_extension import AppApiExtension
|
||||||
@@ -32,7 +31,6 @@ class Program:
|
|||||||
.use_extension(StartupDiscordExtension)
|
.use_extension(StartupDiscordExtension)
|
||||||
.use_extension(StartupModuleExtension)
|
.use_extension(StartupModuleExtension)
|
||||||
.use_extension(StartupMigrationExtension)
|
.use_extension(StartupMigrationExtension)
|
||||||
.use_extension(CleanLogsExtension)
|
|
||||||
.use_extension(DatabaseExtension)
|
.use_extension(DatabaseExtension)
|
||||||
.use_extension(ConfigExtension)
|
.use_extension(ConfigExtension)
|
||||||
.use_extension(InitBotExtension)
|
.use_extension(InitBotExtension)
|
||||||
|
@@ -12,6 +12,7 @@ from modules.boot_log.boot_log_module import BootLogModule
|
|||||||
from modules.config.config_module import ConfigModule
|
from modules.config.config_module import ConfigModule
|
||||||
from modules.database.database_module import DatabaseModule
|
from modules.database.database_module import DatabaseModule
|
||||||
from modules.level.level_module import LevelModule
|
from modules.level.level_module import LevelModule
|
||||||
|
from modules.permission.permission_module import PermissionModule
|
||||||
from modules.short_role_name.short_role_name_module import ShortRoleNameModule
|
from modules.short_role_name.short_role_name_module import ShortRoleNameModule
|
||||||
from modules.special_offers.special_offers_module import SteamSpecialOffersModule
|
from modules.special_offers.special_offers_module import SteamSpecialOffersModule
|
||||||
from modules.technician.technician_module import TechnicianModule
|
from modules.technician.technician_module import TechnicianModule
|
||||||
@@ -29,6 +30,7 @@ class ModuleList:
|
|||||||
ConfigModule, # has to be before db check
|
ConfigModule, # has to be before db check
|
||||||
DatabaseModule,
|
DatabaseModule,
|
||||||
GraphQLModule,
|
GraphQLModule,
|
||||||
|
PermissionModule,
|
||||||
AutoRoleModule,
|
AutoRoleModule,
|
||||||
BaseModule,
|
BaseModule,
|
||||||
LevelModule,
|
LevelModule,
|
||||||
|
@@ -15,7 +15,6 @@ 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
|
||||||
@@ -46,13 +45,14 @@ 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)
|
||||||
|
|
||||||
services.add_translation()
|
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()
|
provider = services.build_service_provider()
|
||||||
# instantiate custom logger
|
# instantiate custom logger
|
||||||
|
@@ -9,9 +9,13 @@ class StartupDiscordExtension(StartupExtensionABC):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
def configure_configuration(
|
||||||
|
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
def configure_services(
|
||||||
|
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||||
|
):
|
||||||
services.add_discord()
|
services.add_discord()
|
||||||
dcc = get_discord_collection(services)
|
dcc = get_discord_collection(services)
|
||||||
|
106
bot/src/bot/startup_migration_extension.py
Normal file
106
bot/src/bot/startup_migration_extension.py
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
from cpl_core.application import StartupExtensionABC
|
||||||
|
from cpl_core.configuration import ConfigurationABC
|
||||||
|
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||||
|
from cpl_core.environment import ApplicationEnvironmentABC
|
||||||
|
|
||||||
|
from bot_data.abc.migration_abc import MigrationABC
|
||||||
|
from bot_data.migration.achievements_migration import AchievementsMigration
|
||||||
|
from bot_data.migration.api_key_migration import ApiKeyMigration
|
||||||
|
from bot_data.migration.api_migration import ApiMigration
|
||||||
|
from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration
|
||||||
|
from bot_data.migration.auto_role_migration import AutoRoleMigration
|
||||||
|
from bot_data.migration.birthday_migration import BirthdayMigration
|
||||||
|
from bot_data.migration.config_feature_flags_migration import (
|
||||||
|
ConfigFeatureFlagsMigration,
|
||||||
|
)
|
||||||
|
from bot_data.migration.config_migration import ConfigMigration
|
||||||
|
from bot_data.migration.db_history_migration import DBHistoryMigration
|
||||||
|
from bot_data.migration.default_role_migration import DefaultRoleMigration
|
||||||
|
from bot_data.migration.fix_updates_migration import FixUpdatesMigration
|
||||||
|
from bot_data.migration.fix_user_history_migration import FixUserHistoryMigration
|
||||||
|
from bot_data.migration.initial_migration import InitialMigration
|
||||||
|
from bot_data.migration.level_migration import LevelMigration
|
||||||
|
from bot_data.migration.remove_stats_migration import RemoveStatsMigration
|
||||||
|
from bot_data.migration.short_role_name_migration import ShortRoleNameMigration
|
||||||
|
from bot_data.migration.short_role_name_only_highest_migration import (
|
||||||
|
ShortRoleNameOnlyHighestMigration,
|
||||||
|
)
|
||||||
|
from bot_data.migration.stats_migration import StatsMigration
|
||||||
|
from bot_data.migration.steam_special_offer_migration import SteamSpecialOfferMigration
|
||||||
|
from bot_data.migration.user_joined_game_server_migration import (
|
||||||
|
UserJoinedGameServerMigration,
|
||||||
|
)
|
||||||
|
from bot_data.migration.user_message_count_per_hour_migration import (
|
||||||
|
UserMessageCountPerHourMigration,
|
||||||
|
)
|
||||||
|
from bot_data.migration.user_warning_migration import UserWarningMigration
|
||||||
|
from bot_data.service.migration_service import MigrationService
|
||||||
|
|
||||||
|
|
||||||
|
class StartupMigrationExtension(StartupExtensionABC):
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def configure_configuration(
|
||||||
|
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def configure_services(
|
||||||
|
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||||
|
):
|
||||||
|
services.add_transient(MigrationService)
|
||||||
|
services.add_transient(MigrationABC, InitialMigration)
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, AutoRoleMigration
|
||||||
|
) # 03.10.2022 #54 - 0.2.2
|
||||||
|
services.add_transient(MigrationABC, ApiMigration) # 15.10.2022 #70 - 0.3.0
|
||||||
|
services.add_transient(MigrationABC, LevelMigration) # 06.11.2022 #25 - 0.3.0
|
||||||
|
services.add_transient(MigrationABC, StatsMigration) # 09.11.2022 #46 - 0.3.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, AutoRoleFix1Migration
|
||||||
|
) # 30.12.2022 #151 - 0.3.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, UserMessageCountPerHourMigration
|
||||||
|
) # 11.01.2023 #168 - 0.3.1
|
||||||
|
services.add_transient(MigrationABC, ApiKeyMigration) # 09.02.2023 #162 - 1.0.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, UserJoinedGameServerMigration
|
||||||
|
) # 12.02.2023 #181 - 1.0.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, RemoveStatsMigration
|
||||||
|
) # 19.02.2023 #190 - 1.0.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, UserWarningMigration
|
||||||
|
) # 21.02.2023 #35 - 1.0.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, DBHistoryMigration
|
||||||
|
) # 06.03.2023 #246 - 1.0.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, AchievementsMigration
|
||||||
|
) # 14.06.2023 #268 - 1.1.0
|
||||||
|
services.add_transient(MigrationABC, ConfigMigration) # 19.07.2023 #127 - 1.1.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, ConfigFeatureFlagsMigration
|
||||||
|
) # 15.08.2023 #334 - 1.1.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, DefaultRoleMigration
|
||||||
|
) # 24.09.2023 #360 - 1.1.3
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, ShortRoleNameMigration
|
||||||
|
) # 28.09.2023 #378 - 1.1.7
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, FixUpdatesMigration
|
||||||
|
) # 28.09.2023 #378 - 1.1.7
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, ShortRoleNameOnlyHighestMigration
|
||||||
|
) # 02.10.2023 #391 - 1.1.9
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, FixUserHistoryMigration
|
||||||
|
) # 10.10.2023 #401 - 1.2.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, BirthdayMigration
|
||||||
|
) # 10.10.2023 #401 - 1.2.0
|
||||||
|
services.add_transient(
|
||||||
|
MigrationABC, SteamSpecialOfferMigration
|
||||||
|
) # 10.10.2023 #188 - 1.2.0
|
@@ -18,11 +18,15 @@ class StartupModuleExtension(StartupExtensionABC):
|
|||||||
|
|
||||||
self._modules = ModuleList.get_modules()
|
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._config = config
|
||||||
self._feature_flags = config.get_configuration(FeatureFlagsSettings)
|
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()
|
provider = services.build_service_provider()
|
||||||
dc_collection: DiscordCollectionABC = provider.get_service(DiscordCollectionABC)
|
dc_collection: DiscordCollectionABC = provider.get_service(DiscordCollectionABC)
|
||||||
|
|
||||||
|
@@ -8,39 +8,44 @@ from cpl_core.dependency_injection import ServiceCollectionABC
|
|||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
from cpl_core.environment import ApplicationEnvironmentABC
|
||||||
|
|
||||||
from bot_core.configuration.bot_logging_settings import BotLoggingSettings
|
from bot_core.configuration.bot_logging_settings import BotLoggingSettings
|
||||||
from bot_core.environment_variables import MAINTENANCE, MIGRATION_ONLY
|
|
||||||
|
|
||||||
|
|
||||||
class StartupSettingsExtension(StartupExtensionABC):
|
class StartupSettingsExtension(StartupExtensionABC):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._start_time = datetime.now()
|
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
|
# 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__)))
|
environment.set_working_directory(os.path.dirname(os.path.realpath(__file__)))
|
||||||
configuration.add_environment_variables("SDB_")
|
configuration.add_environment_variables("KDB_")
|
||||||
configuration.add_environment_variables("DISCORD_")
|
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.json", optional=False)
|
||||||
configuration.add_json_file(f"config/appsettings.{environment.environment_name}.json", optional=True)
|
configuration.add_json_file(
|
||||||
configuration.add_json_file(f"config/appsettings.{environment.host_name}.json", optional=True)
|
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
|
# load feature-flags
|
||||||
configuration.add_json_file(f"config/feature-flags.json", optional=False)
|
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(
|
||||||
configuration.add_json_file(f"config/feature-flags.{environment.host_name}.json", optional=True)
|
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))
|
configuration.add_configuration("Startup_StartTime", str(self._start_time))
|
||||||
self._configure_settings_with_sub_settings(
|
self._configure_settings_with_sub_settings(
|
||||||
configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key
|
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
|
pass
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -52,4 +57,6 @@ class StartupSettingsExtension(StartupExtensionABC):
|
|||||||
return
|
return
|
||||||
|
|
||||||
for sub_settings in list_atr(settings):
|
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,8 +90,7 @@
|
|||||||
"booting": "Ich fahre gerade hoch...",
|
"booting": "Ich fahre gerade hoch...",
|
||||||
"restart": "Muss neue Kekse holen...",
|
"restart": "Muss neue Kekse holen...",
|
||||||
"running": "Ich esse Kekse :D",
|
"running": "Ich esse Kekse :D",
|
||||||
"shutdown": "Ich werde bestimmt wieder kommen...",
|
"shutdown": "Ich werde bestimmt wieder kommen..."
|
||||||
"maintenance": "In Wartung!"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.abc"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -40,11 +40,15 @@ class AuthServiceABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_filtered_auth_users_async(self, criteria: AuthUserSelectCriteria) -> AuthUserFilteredResultDTO:
|
async def get_filtered_auth_users_async(
|
||||||
|
self, criteria: AuthUserSelectCriteria
|
||||||
|
) -> AuthUserFilteredResultDTO:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -3,7 +3,9 @@ from abc import ABC, abstractmethod
|
|||||||
|
|
||||||
class SelectCriteriaABC(ABC):
|
class SelectCriteriaABC(ABC):
|
||||||
@abstractmethod
|
@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_index = page_index
|
||||||
self.page_size = page_size
|
self.page_size = page_size
|
||||||
self.sort_direction = sort_direction
|
self.sort_direction = sort_direction
|
||||||
|
@@ -57,7 +57,9 @@ class Api(Flask):
|
|||||||
# Added async_mode see link below
|
# Added async_mode see link below
|
||||||
# https://github.com/miguelgrinberg/Flask-SocketIO/discussions/1849
|
# https://github.com/miguelgrinberg/Flask-SocketIO/discussions/1849
|
||||||
# https://stackoverflow.com/questions/39370848/flask-socket-io-sometimes-client-calls-freeze-the-server
|
# 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("connect", self.on_connect)
|
||||||
self._socketio.on_event("disconnect", self.on_disconnect)
|
self._socketio.on_event("disconnect", self.on_disconnect)
|
||||||
|
|
||||||
@@ -143,7 +145,9 @@ class Api(Flask):
|
|||||||
data = request.get_data()
|
data = request.get_data()
|
||||||
data = "" if len(data) == 0 else str(data.decode(encoding="utf-8"))
|
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)
|
self._logger.trace(__name__, text)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
@@ -158,7 +162,9 @@ class Api(Flask):
|
|||||||
# from waitress import serve
|
# from waitress import serve
|
||||||
# https://docs.pylonsproject.org/projects/waitress/en/stable/arguments.html
|
# 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)
|
# 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)
|
wsgi.server(self._socket, self, log_output=False)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
@@ -26,15 +26,21 @@ class ApiModule(ModuleABC):
|
|||||||
def __init__(self, dc: DiscordCollectionABC):
|
def __init__(self, dc: DiscordCollectionABC):
|
||||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.api_module)
|
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
|
cwd = env.working_directory
|
||||||
env.set_working_directory(os.path.dirname(os.path.realpath(__file__)))
|
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.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)
|
config.add_json_file(f"config/apisettings.{env.host_name}.json", optional=True)
|
||||||
env.set_working_directory(cwd)
|
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(EMailClientABC, EMailClient)
|
||||||
|
|
||||||
services.add_singleton(ApiThread)
|
services.add_singleton(ApiThread)
|
||||||
|
@@ -12,7 +12,9 @@ class AppApiExtension(ApplicationExtensionABC):
|
|||||||
ApplicationExtensionABC.__init__(self)
|
ApplicationExtensionABC.__init__(self)
|
||||||
|
|
||||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
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):
|
if not feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"Version": {
|
"Version": {
|
||||||
"Major": "1",
|
"Major": "1",
|
||||||
"Minor": "2",
|
"Minor": "2",
|
||||||
"Micro": "5"
|
"Micro": "0"
|
||||||
},
|
},
|
||||||
"Author": "",
|
"Author": "",
|
||||||
"AuthorEmail": "",
|
"AuthorEmail": "",
|
||||||
|
Submodule bot/src/bot_api/config deleted from 521951b8ab
@@ -15,7 +15,7 @@ __title__ = "bot_api.configuration"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports
|
# imports
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -16,7 +16,9 @@ class AuthenticationSettings(ConfigurationModelABC):
|
|||||||
self._issuer = "" if issuer is None else issuer
|
self._issuer = "" if issuer is None else issuer
|
||||||
self._audience = "" if audience is None else audience
|
self._audience = "" if audience is None else audience
|
||||||
self._token_expire_time = 0 if token_expire_time is None else token_expire_time
|
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
|
@property
|
||||||
def secret_key(self) -> str:
|
def secret_key(self) -> str:
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.controller"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -14,10 +14,7 @@ from bot_api.model.reset_password_dto import ResetPasswordDTO
|
|||||||
from bot_api.model.token_dto import TokenDTO
|
from bot_api.model.token_dto import TokenDTO
|
||||||
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
from bot_api.model.update_auth_user_dto import UpdateAuthUserDTO
|
||||||
from bot_api.route.route import Route
|
from bot_api.route.route import Route
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|
||||||
from bot_data.model.auth_role_enum import AuthRoleEnum
|
from bot_data.model.auth_role_enum import AuthRoleEnum
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
|
||||||
|
|
||||||
|
|
||||||
class AuthController:
|
class AuthController:
|
||||||
@@ -33,7 +30,6 @@ class AuthController:
|
|||||||
mail_settings: EMailClientSettings,
|
mail_settings: EMailClientSettings,
|
||||||
mailer: EMailClientABC,
|
mailer: EMailClientABC,
|
||||||
auth_service: AuthServiceABC,
|
auth_service: AuthServiceABC,
|
||||||
technician_config: TechnicianConfig,
|
|
||||||
):
|
):
|
||||||
self._config = config
|
self._config = config
|
||||||
self._env = env
|
self._env = env
|
||||||
@@ -43,7 +39,6 @@ class AuthController:
|
|||||||
self._mail_settings = mail_settings
|
self._mail_settings = mail_settings
|
||||||
self._mailer = mailer
|
self._mailer = mailer
|
||||||
self._auth_service = auth_service
|
self._auth_service = auth_service
|
||||||
self._technician_config = technician_config
|
|
||||||
|
|
||||||
@Route.get(f"{BasePath}/users")
|
@Route.get(f"{BasePath}/users")
|
||||||
@Route.authorize(role=AuthRoleEnum.admin)
|
@Route.authorize(role=AuthRoleEnum.admin)
|
||||||
@@ -75,33 +70,22 @@ class AuthController:
|
|||||||
|
|
||||||
@Route.post(f"{BasePath}/register")
|
@Route.post(f"{BasePath}/register")
|
||||||
async def register(self):
|
async def register(self):
|
||||||
if not FeatureFlagsSettings.get_flag_from_dict(
|
dto: AuthUserDTO = JSONProcessor.process(
|
||||||
self._technician_config.feature_flags, FeatureFlagsEnum.basic_registration
|
AuthUserDTO, request.get_json(force=True, silent=True)
|
||||||
):
|
)
|
||||||
return
|
|
||||||
|
|
||||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
|
||||||
self._auth_service.add_auth_user(dto)
|
self._auth_service.add_auth_user(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/register-by-id/<id>")
|
@Route.post(f"{BasePath}/register-by-id/<id>")
|
||||||
async def register_id(self, id: str):
|
async def register_id(self, id: str):
|
||||||
if not FeatureFlagsSettings.get_flag_from_dict(
|
|
||||||
self._technician_config.feature_flags, FeatureFlagsEnum.basic_registration
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
result = await self._auth_service.confirm_email_async(id)
|
result = await self._auth_service.confirm_email_async(id)
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/login")
|
@Route.post(f"{BasePath}/login")
|
||||||
async def login(self) -> Response:
|
async def login(self) -> Response:
|
||||||
if not FeatureFlagsSettings.get_flag_from_dict(
|
dto: AuthUserDTO = JSONProcessor.process(
|
||||||
self._technician_config.feature_flags, FeatureFlagsEnum.basic_login
|
AuthUserDTO, request.get_json(force=True, silent=True)
|
||||||
):
|
)
|
||||||
return jsonify({})
|
|
||||||
|
|
||||||
dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True))
|
|
||||||
result = await self._auth_service.login_async(dto)
|
result = await self._auth_service.login_async(dto)
|
||||||
return jsonify(result.to_dict())
|
return jsonify(result.to_dict())
|
||||||
|
|
||||||
@@ -120,11 +104,6 @@ class AuthController:
|
|||||||
|
|
||||||
@Route.post(f"{BasePath}/forgot-password/<email>")
|
@Route.post(f"{BasePath}/forgot-password/<email>")
|
||||||
async def forgot_password(self, email: str):
|
async def forgot_password(self, email: str):
|
||||||
if not FeatureFlagsSettings.get_flag_from_dict(
|
|
||||||
self._technician_config.feature_flags, FeatureFlagsEnum.basic_login
|
|
||||||
):
|
|
||||||
return "", 409
|
|
||||||
|
|
||||||
await self._auth_service.forgot_password_async(email)
|
await self._auth_service.forgot_password_async(email)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@@ -135,45 +114,52 @@ class AuthController:
|
|||||||
|
|
||||||
@Route.post(f"{BasePath}/reset-password")
|
@Route.post(f"{BasePath}/reset-password")
|
||||||
async def reset_password(self):
|
async def reset_password(self):
|
||||||
if not FeatureFlagsSettings.get_flag_from_dict(
|
dto: ResetPasswordDTO = JSONProcessor.process(
|
||||||
self._technician_config.feature_flags, FeatureFlagsEnum.basic_login
|
ResetPasswordDTO, request.get_json(force=True, silent=True)
|
||||||
):
|
)
|
||||||
return "", 409
|
|
||||||
|
|
||||||
dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True))
|
|
||||||
await self._auth_service.reset_password_async(dto)
|
await self._auth_service.reset_password_async(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/update-user")
|
@Route.post(f"{BasePath}/update-user")
|
||||||
@Route.authorize
|
@Route.authorize
|
||||||
async def update_user(self):
|
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)
|
await self._auth_service.update_user_async(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/update-user-as-admin")
|
@Route.post(f"{BasePath}/update-user-as-admin")
|
||||||
@Route.authorize(role=AuthRoleEnum.admin)
|
@Route.authorize(role=AuthRoleEnum.admin)
|
||||||
async def update_user_as_admin(self):
|
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)
|
await self._auth_service.update_user_as_admin_async(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/refresh")
|
@Route.post(f"{BasePath}/refresh")
|
||||||
async def refresh(self) -> Response:
|
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)
|
result = await self._auth_service.refresh_async(dto)
|
||||||
return jsonify(result.to_dict())
|
return jsonify(result.to_dict())
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/revoke")
|
@Route.post(f"{BasePath}/revoke")
|
||||||
async def revoke(self):
|
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)
|
await self._auth_service.revoke_async(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/delete-user")
|
@Route.post(f"{BasePath}/delete-user")
|
||||||
@Route.authorize(role=AuthRoleEnum.admin)
|
@Route.authorize(role=AuthRoleEnum.admin)
|
||||||
async def delete_user(self):
|
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)
|
await self._auth_service.delete_auth_user_async(dto)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
|
@@ -12,9 +12,6 @@ from bot_api.logging.api_logger import ApiLogger
|
|||||||
from bot_api.model.settings_dto import SettingsDTO
|
from bot_api.model.settings_dto import SettingsDTO
|
||||||
from bot_api.model.version_dto import VersionDTO
|
from bot_api.model.version_dto import VersionDTO
|
||||||
from bot_api.route.route import Route
|
from bot_api.route.route import Route
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
|
||||||
|
|
||||||
|
|
||||||
class GuiController:
|
class GuiController:
|
||||||
@@ -85,11 +82,3 @@ class GuiController:
|
|||||||
)
|
)
|
||||||
self._mailer.send_mail(mail)
|
self._mailer.send_mail(mail)
|
||||||
return "", 200
|
return "", 200
|
||||||
|
|
||||||
@Route.get(f"{BasePath}/has-feature-flag/<flag>")
|
|
||||||
async def has_feature_flag(self, flag: str):
|
|
||||||
settings: TechnicianConfig = self._config.get_configuration(TechnicianConfig)
|
|
||||||
return {
|
|
||||||
"key": flag,
|
|
||||||
"value": FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum(flag)),
|
|
||||||
}
|
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.event"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.exception"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.filter"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -13,7 +13,9 @@ class AuthUserSelectCriteria(SelectCriteriaABC):
|
|||||||
email: str,
|
email: str,
|
||||||
auth_role: int,
|
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.first_name = first_name
|
||||||
self.last_name = last_name
|
self.last_name = last_name
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.filter.discord"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -10,6 +10,8 @@ class ServerSelectCriteria(SelectCriteriaABC):
|
|||||||
sort_column: str,
|
sort_column: str,
|
||||||
name: 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
|
self.name = name
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.logging"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.model"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.model.discord"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -11,7 +11,9 @@ class ErrorDTO(DtoABC):
|
|||||||
def __init__(self, error_code: Optional[ServiceErrorCode], message: str):
|
def __init__(self, error_code: Optional[ServiceErrorCode], message: str):
|
||||||
DtoABC.__init__(self)
|
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
|
self._message = message
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@@ -34,7 +34,9 @@ class UpdateAuthUserDTO(DtoABC):
|
|||||||
def from_dict(self, values: dict):
|
def from_dict(self, values: dict):
|
||||||
self._auth_user = AuthUserDTO().from_dict(values["authUser"])
|
self._auth_user = AuthUserDTO().from_dict(values["authUser"])
|
||||||
self._new_auth_user = AuthUserDTO().from_dict(values["newAuthUser"])
|
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:
|
def to_dict(self) -> dict:
|
||||||
return {
|
return {
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.route"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -65,7 +65,9 @@ class Route:
|
|||||||
by_api_key=False,
|
by_api_key=False,
|
||||||
):
|
):
|
||||||
if f is None:
|
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)
|
@wraps(f)
|
||||||
async def decorator(*args, **kwargs):
|
async def decorator(*args, **kwargs):
|
||||||
@@ -76,7 +78,9 @@ class Route:
|
|||||||
api_key = None
|
api_key = None
|
||||||
if "Authorization" in request.headers:
|
if "Authorization" in request.headers:
|
||||||
if " " not in request.headers.get("Authorization"):
|
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)
|
error = ErrorDTO(ex.error_code, ex.message)
|
||||||
return jsonify(error.to_dict()), 401
|
return jsonify(error.to_dict()), 401
|
||||||
|
|
||||||
@@ -98,7 +102,9 @@ class Route:
|
|||||||
return jsonify(e), 500
|
return jsonify(e), 500
|
||||||
|
|
||||||
if not valid:
|
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)
|
error = ErrorDTO(ex.error_code, ex.message)
|
||||||
return jsonify(error.to_dict()), 401
|
return jsonify(error.to_dict()), 401
|
||||||
|
|
||||||
@@ -110,7 +116,9 @@ class Route:
|
|||||||
return jsonify(error.to_dict()), 401
|
return jsonify(error.to_dict()), 401
|
||||||
|
|
||||||
if cls._auth_users is None or cls._auth is None:
|
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)
|
error = ErrorDTO(ex.error_code, ex.message)
|
||||||
return jsonify(error.to_dict()), 401
|
return jsonify(error.to_dict()), 401
|
||||||
|
|
||||||
@@ -132,7 +140,9 @@ class Route:
|
|||||||
return jsonify(error.to_dict()), 401
|
return jsonify(error.to_dict()), 401
|
||||||
|
|
||||||
if role is not None and user.auth_role.value < role.value:
|
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)
|
error = ErrorDTO(ex.error_code, ex.message)
|
||||||
return jsonify(error.to_dict()), 403
|
return jsonify(error.to_dict()), 403
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.service"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports
|
# imports
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -90,7 +90,9 @@ class AuthService(AuthServiceABC):
|
|||||||
|
|
||||||
def _get_api_key_str(self, api_key: ApiKey) -> str:
|
def _get_api_key_str(self, api_key: ApiKey) -> str:
|
||||||
return hashlib.sha256(
|
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()
|
).hexdigest()
|
||||||
|
|
||||||
def generate_token(self, user: AuthUser) -> str:
|
def generate_token(self, user: AuthUser) -> str:
|
||||||
@@ -99,7 +101,8 @@ class AuthService(AuthServiceABC):
|
|||||||
"user_id": user.id,
|
"user_id": user.id,
|
||||||
"email": user.email,
|
"email": user.email,
|
||||||
"role": user.auth_role.value,
|
"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,
|
"iss": self._auth_settings.issuer,
|
||||||
"aud": self._auth_settings.audience,
|
"aud": self._auth_settings.audience,
|
||||||
},
|
},
|
||||||
@@ -155,7 +158,9 @@ class AuthService(AuthServiceABC):
|
|||||||
def _create_and_save_refresh_token(self, user: AuthUser) -> str:
|
def _create_and_save_refresh_token(self, user: AuthUser) -> str:
|
||||||
token = str(uuid.uuid4())
|
token = str(uuid.uuid4())
|
||||||
user.refresh_token = token
|
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._auth_users.update_auth_user(user)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
return token
|
return token
|
||||||
@@ -188,8 +193,12 @@ class AuthService(AuthServiceABC):
|
|||||||
|
|
||||||
self._send_link_mail(
|
self._send_link_mail(
|
||||||
user.email,
|
user.email,
|
||||||
self._t.transform("api.auth.confirmation.subject").format(user.first_name, user.last_name),
|
self._t.transform("api.auth.confirmation.subject").format(
|
||||||
self._t.transform("api.auth.confirmation.message").format(url, user.confirmation_id),
|
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):
|
def _send_forgot_password_id_to_user(self, user: AuthUser):
|
||||||
@@ -199,28 +208,38 @@ class AuthService(AuthServiceABC):
|
|||||||
|
|
||||||
self._send_link_mail(
|
self._send_link_mail(
|
||||||
user.email,
|
user.email,
|
||||||
self._t.transform("api.auth.forgot_password.subject").format(user.first_name, user.last_name),
|
self._t.transform("api.auth.forgot_password.subject").format(
|
||||||
self._t.transform("api.auth.forgot_password.message").format(url, user.forgot_password_id),
|
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]:
|
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))
|
result = self._auth_users.get_all_auth_users().select(lambda x: AUT.to_dto(x))
|
||||||
return List(AuthUserDTO, result)
|
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)
|
users = self._auth_users.get_filtered_auth_users(criteria)
|
||||||
result = users.result.select(lambda x: AUT.to_dto(x))
|
result = users.result.select(lambda x: AUT.to_dto(x))
|
||||||
|
|
||||||
return AuthUserFilteredResultDTO(List(AuthUserDTO, result), users.total_count)
|
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:
|
try:
|
||||||
# todo: check if logged in user is admin then send mail
|
# todo: check if logged in user is admin then send mail
|
||||||
user = self._auth_users.get_auth_user_by_email(email)
|
user = self._auth_users.get_auth_user_by_email(email)
|
||||||
return AUT.to_dto(user, password=user.password if with_password else None)
|
return AUT.to_dto(user, password=user.password if with_password else None)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.error(__name__, f"AuthUser not found", 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]:
|
async def find_auth_user_by_email_async(self, email: str) -> Optional[AuthUser]:
|
||||||
user = self._auth_users.find_auth_user_by_email(email)
|
user = self._auth_users.find_auth_user_by_email(email)
|
||||||
@@ -238,16 +257,22 @@ class AuthService(AuthServiceABC):
|
|||||||
user.password_salt = uuid.uuid4()
|
user.password_salt = uuid.uuid4()
|
||||||
user.password = self._hash_sha256(user_dto.password, user.password_salt)
|
user.password = self._hash_sha256(user_dto.password, user.password_salt)
|
||||||
if not self._is_email_valid(user.email):
|
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:
|
try:
|
||||||
user.confirmation_id = uuid.uuid4()
|
user.confirmation_id = uuid.uuid4()
|
||||||
self._auth_users.add_auth_user(user)
|
self._auth_users.add_auth_user(user)
|
||||||
self._send_confirmation_id_to_user(user)
|
self._send_confirmation_id_to_user(user)
|
||||||
self._db.save_changes()
|
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:
|
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")
|
raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail")
|
||||||
|
|
||||||
async def add_auth_user_by_oauth_async(self, dto: OAuthDTO):
|
async def add_auth_user_by_oauth_async(self, dto: OAuthDTO):
|
||||||
@@ -263,14 +288,20 @@ class AuthService(AuthServiceABC):
|
|||||||
db_user.first_name = dto.user.first_name
|
db_user.first_name = dto.user.first_name
|
||||||
db_user.last_name = dto.user.last_name
|
db_user.last_name = dto.user.last_name
|
||||||
db_user.password_salt = uuid.uuid4()
|
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.oauth_id = None
|
||||||
db_user.confirmation_id = uuid.uuid4()
|
db_user.confirmation_id = uuid.uuid4()
|
||||||
self._send_confirmation_id_to_user(db_user)
|
self._send_confirmation_id_to_user(db_user)
|
||||||
self._auth_users.update_auth_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:
|
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")
|
raise ServiceException(ServiceErrorCode.UnableToAdd, "Invalid E-Mail")
|
||||||
|
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
@@ -280,14 +311,16 @@ class AuthService(AuthServiceABC):
|
|||||||
raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty")
|
raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty")
|
||||||
|
|
||||||
if update_user_dto.auth_user is None:
|
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:
|
if update_user_dto.new_auth_user is None:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty")
|
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(
|
if not self._is_email_valid(
|
||||||
update_user_dto.new_auth_user.email
|
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")
|
raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail")
|
||||||
|
|
||||||
user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email)
|
user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email)
|
||||||
@@ -300,7 +333,8 @@ class AuthService(AuthServiceABC):
|
|||||||
# update first name
|
# update first name
|
||||||
if (
|
if (
|
||||||
update_user_dto.new_auth_user.first_name is not None
|
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
|
user.first_name = update_user_dto.new_auth_user.first_name
|
||||||
|
|
||||||
@@ -308,7 +342,8 @@ class AuthService(AuthServiceABC):
|
|||||||
if (
|
if (
|
||||||
update_user_dto.new_auth_user.last_name is not None
|
update_user_dto.new_auth_user.last_name is not None
|
||||||
and update_user_dto.new_auth_user.last_name != ""
|
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
|
user.last_name = update_user_dto.new_auth_user.last_name
|
||||||
|
|
||||||
@@ -318,22 +353,33 @@ class AuthService(AuthServiceABC):
|
|||||||
and update_user_dto.new_auth_user.email != ""
|
and update_user_dto.new_auth_user.email != ""
|
||||||
and update_user_dto.auth_user.email != 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:
|
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
|
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:
|
if update_user_dto.auth_user.password != user.password:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong password")
|
raise ServiceException(ServiceErrorCode.InvalidUser, "Wrong password")
|
||||||
|
|
||||||
# update password
|
# update password
|
||||||
if (
|
if (
|
||||||
update_user_dto.new_auth_user.password is not None
|
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_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._auth_users.update_auth_user(user)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
@@ -343,23 +389,31 @@ class AuthService(AuthServiceABC):
|
|||||||
raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty")
|
raise ServiceException(ServiceErrorCode.InvalidData, f"User is empty")
|
||||||
|
|
||||||
if update_user_dto.auth_user is None:
|
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:
|
if update_user_dto.new_auth_user is None:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, f"New user is empty")
|
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(
|
if not self._is_email_valid(
|
||||||
update_user_dto.new_auth_user.email
|
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")
|
raise ServiceException(ServiceErrorCode.InvalidData, f"Invalid E-Mail")
|
||||||
|
|
||||||
user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email)
|
user = self._auth_users.find_auth_user_by_email(update_user_dto.auth_user.email)
|
||||||
if user is None:
|
if user is None:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidUser, "User not found")
|
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
|
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()
|
user.confirmation_id = uuid.uuid4()
|
||||||
# else
|
# else
|
||||||
# raise ServiceException(ServiceErrorCode.InvalidUser, 'E-Mail not confirmed')
|
# raise ServiceException(ServiceErrorCode.InvalidUser, 'E-Mail not confirmed')
|
||||||
@@ -367,7 +421,8 @@ class AuthService(AuthServiceABC):
|
|||||||
# update first name
|
# update first name
|
||||||
if (
|
if (
|
||||||
update_user_dto.new_auth_user.first_name is not None
|
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
|
user.first_name = update_user_dto.new_auth_user.first_name
|
||||||
|
|
||||||
@@ -375,7 +430,8 @@ class AuthService(AuthServiceABC):
|
|||||||
if (
|
if (
|
||||||
update_user_dto.new_auth_user.last_name is not None
|
update_user_dto.new_auth_user.last_name is not None
|
||||||
and update_user_dto.new_auth_user.last_name != ""
|
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
|
user.last_name = update_user_dto.new_auth_user.last_name
|
||||||
|
|
||||||
@@ -385,19 +441,28 @@ class AuthService(AuthServiceABC):
|
|||||||
and update_user_dto.new_auth_user.email != ""
|
and update_user_dto.new_auth_user.email != ""
|
||||||
and update_user_dto.auth_user.email != 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:
|
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
|
user.email = update_user_dto.new_auth_user.email
|
||||||
|
|
||||||
# update password
|
# update password
|
||||||
if (
|
if (
|
||||||
update_user_dto.new_auth_user.password is not None
|
update_user_dto.new_auth_user.password is not None
|
||||||
and update_user_dto.change_password
|
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_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
|
# update role
|
||||||
if (
|
if (
|
||||||
@@ -416,7 +481,9 @@ class AuthService(AuthServiceABC):
|
|||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.error(__name__, f"Cannot delete user", 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):
|
async def delete_auth_user_async(self, user_dto: AuthUser):
|
||||||
try:
|
try:
|
||||||
@@ -500,7 +567,9 @@ class AuthService(AuthServiceABC):
|
|||||||
if user.id in user_ids:
|
if user.id in user_ids:
|
||||||
continue
|
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:
|
if db_user.confirmation_id is not None and not added_user:
|
||||||
raise ServiceException(ServiceErrorCode.Forbidden, "E-Mail not verified")
|
raise ServiceException(ServiceErrorCode.Forbidden, "E-Mail not verified")
|
||||||
@@ -530,13 +599,19 @@ class AuthService(AuthServiceABC):
|
|||||||
):
|
):
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, "Token expired")
|
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:
|
except Exception as e:
|
||||||
self._logger.error(__name__, f"Refreshing token failed", e)
|
self._logger.error(__name__, f"Refreshing token failed", e)
|
||||||
return TokenDTO("", "")
|
return TokenDTO("", "")
|
||||||
|
|
||||||
async def revoke_async(self, token_dto: 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")
|
raise ServiceException(ServiceErrorCode.InvalidData, "Token not set")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -589,7 +664,9 @@ class AuthService(AuthServiceABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if user.confirmation_id is not None:
|
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 == "":
|
if user.password is None or rp_dto.password == "":
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, f"Password not set")
|
raise ServiceException(ServiceErrorCode.InvalidData, f"Password not set")
|
||||||
|
@@ -53,13 +53,17 @@ class DiscordService:
|
|||||||
if role != AuthRoleEnum.admin:
|
if role != AuthRoleEnum.admin:
|
||||||
auth_user = self._auth_users.find_auth_user_by_email(token["email"])
|
auth_user = self._auth_users.find_auth_user_by_email(token["email"])
|
||||||
if auth_user is not None:
|
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 = servers.where(lambda x: x.id in user_ids)
|
||||||
|
|
||||||
servers = List(ServerDTO, servers)
|
servers = List(ServerDTO, servers)
|
||||||
return servers.select(self._to_dto).where(lambda x: x.name != "")
|
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()
|
token = self._auth.get_decoded_token_from_request()
|
||||||
if token is None or "email" not in token or "role" not in token:
|
if token is None or "email" not in token or "role" not in token:
|
||||||
raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid")
|
raise ServiceException(ServiceErrorCode.InvalidData, "Token invalid")
|
||||||
@@ -70,15 +74,22 @@ class DiscordService:
|
|||||||
if role != AuthRoleEnum.admin:
|
if role != AuthRoleEnum.admin:
|
||||||
auth_user = self._auth_users.find_auth_user_by_email(token["email"])
|
auth_user = self._auth_users.find_auth_user_by_email(token["email"])
|
||||||
if auth_user is not None:
|
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(
|
||||||
filtered_result.result = filtered_result.result.where(lambda x: x.id in user_ids)
|
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)
|
result = List(ServerDTO, servers)
|
||||||
|
|
||||||
if criteria.name is not None and criteria.name != "":
|
if criteria.name is not None and criteria.name != "":
|
||||||
result = result.where(
|
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())
|
return ServerFilteredResultDTO(List(ServerDTO, result), servers.count())
|
||||||
@@ -87,5 +98,7 @@ class DiscordService:
|
|||||||
server = self._servers.get_server_by_id(id)
|
server = self._servers.get_server_by_id(id)
|
||||||
guild = self._bot.get_guild(server.discord_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
|
return server_dto
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_api.transformer"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -10,7 +10,7 @@ from bot_api.model.user_dto import UserDTO
|
|||||||
from bot_data.model.auth_role_enum import AuthRoleEnum
|
from bot_data.model.auth_role_enum import AuthRoleEnum
|
||||||
from bot_data.model.auth_user import AuthUser
|
from bot_data.model.auth_user import AuthUser
|
||||||
from bot_data.model.user import User
|
from bot_data.model.user import User
|
||||||
from bot_core.abc.permission_service_abc import PermissionServiceABC
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
|
|
||||||
|
|
||||||
class AuthUserTransformer(TransformerABC):
|
class AuthUserTransformer(TransformerABC):
|
||||||
@@ -27,27 +27,35 @@ class AuthUserTransformer(TransformerABC):
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
datetime.now(),
|
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,
|
auth_user_id=0 if dto.id is None else dto.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ServiceProviderABC.inject
|
@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)
|
guild = bot.get_guild(user.server.discord_id)
|
||||||
member = guild.get_member(user.discord_id)
|
member = guild.get_member(user.discord_id)
|
||||||
return permissions.is_member_technician(member)
|
return permissions.is_member_technician(member)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ServiceProviderABC.inject
|
@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)
|
guild = bot.get_guild(user.server.discord_id)
|
||||||
member = guild.get_member(user.discord_id)
|
member = guild.get_member(user.discord_id)
|
||||||
return permissions.is_member_admin(member)
|
return permissions.is_member_admin(member)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ServiceProviderABC.inject
|
@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)
|
guild = bot.get_guild(user.server.discord_id)
|
||||||
member = guild.get_member(user.discord_id)
|
member = guild.get_member(user.discord_id)
|
||||||
return permissions.is_member_moderator(member)
|
return permissions.is_member_moderator(member)
|
||||||
|
@@ -13,7 +13,9 @@ class ServerTransformer(TransformerABC):
|
|||||||
return Server(dto.discord_id)
|
return Server(dto.discord_id)
|
||||||
|
|
||||||
@staticmethod
|
@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(
|
return ServerDTO(
|
||||||
db.id,
|
db.id,
|
||||||
db.discord_id,
|
db.discord_id,
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports
|
# imports
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.abc"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -45,17 +45,9 @@ class ClientUtilsABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List:
|
def get_auto_complete_list(
|
||||||
pass
|
self, _l: List, current: str, select: Callable = None
|
||||||
|
) -> List:
|
||||||
@abstractmethod
|
|
||||||
def update_user_message_xp_count_by_hour(
|
|
||||||
self,
|
|
||||||
created_at: datetime,
|
|
||||||
user: User,
|
|
||||||
settings: ServerConfig,
|
|
||||||
is_reaction: bool = False,
|
|
||||||
):
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@@ -85,7 +77,3 @@ class ClientUtilsABC(ABC):
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def set_maintenance_mode(self, state: bool):
|
|
||||||
pass
|
|
||||||
|
@@ -18,7 +18,9 @@ class CustomFileLoggerABC(Logger, ABC):
|
|||||||
env: ApplicationEnvironmentABC,
|
env: ApplicationEnvironmentABC,
|
||||||
):
|
):
|
||||||
self._key = key
|
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)
|
Logger.__init__(self, self._settings, time_format, env)
|
||||||
self._begin_log()
|
self._begin_log()
|
||||||
|
|
||||||
@@ -32,7 +34,9 @@ class CustomFileLoggerABC(Logger, ABC):
|
|||||||
self.info(__name__, f"Starting...")
|
self.info(__name__, f"Starting...")
|
||||||
self._console = LoggingLevelEnum(console_level)
|
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(" ")
|
names = name_list_as_str.split(" ")
|
||||||
log_level = level.name
|
log_level = level.name
|
||||||
string = f"<{self._get_datetime_now()}> [ {log_level} ]"
|
string = f"<{self._get_datetime_now()}> [ {log_level} ]"
|
||||||
|
@@ -13,7 +13,9 @@ class MessageServiceABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -6,7 +6,6 @@ from cpl_core.dependency_injection import ServiceProviderABC
|
|||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from bot_core.environment_variables import MAINTENANCE
|
|
||||||
from bot_core.logging.task_logger import TaskLogger
|
from bot_core.logging.task_logger import TaskLogger
|
||||||
|
|
||||||
|
|
||||||
@@ -16,17 +15,15 @@ class TaskABC(commands.Cog):
|
|||||||
commands.Cog.__init__(self)
|
commands.Cog.__init__(self)
|
||||||
|
|
||||||
@ServiceProviderABC.inject
|
@ServiceProviderABC.inject
|
||||||
def _is_maintenance(self, config: ConfigurationABC) -> bool:
|
async def _wait_until_ready(
|
||||||
return config.get_configuration(MAINTENANCE) is True
|
self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC
|
||||||
|
):
|
||||||
@ServiceProviderABC.inject
|
logger.debug(__name__, f"Waiting before {type(self).__name__}")
|
||||||
async def _wait_until_ready(self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC):
|
|
||||||
logger.debug(__name__, f"Waiting before ready {type(self).__name__}")
|
|
||||||
await bot.wait_until_ready()
|
await bot.wait_until_ready()
|
||||||
|
|
||||||
async def wait():
|
async def wait():
|
||||||
is_ready = config.get_configuration("IS_READY") is True
|
is_ready = config.get_configuration("IS_READY")
|
||||||
if not is_ready:
|
if is_ready != "true":
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
await wait()
|
await wait()
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"Version": {
|
"Version": {
|
||||||
"Major": "1",
|
"Major": "1",
|
||||||
"Minor": "2",
|
"Minor": "2",
|
||||||
"Micro": "5"
|
"Micro": "0"
|
||||||
},
|
},
|
||||||
"Author": "Sven Heidemann",
|
"Author": "Sven Heidemann",
|
||||||
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
"AuthorEmail": "sven.heidemann@sh-edraft.de",
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.configuration"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,6 +15,7 @@ class FeatureFlagsEnum(Enum):
|
|||||||
database_module = "DatabaseModule"
|
database_module = "DatabaseModule"
|
||||||
level_module = "LevelModule"
|
level_module = "LevelModule"
|
||||||
moderator_module = "ModeratorModule"
|
moderator_module = "ModeratorModule"
|
||||||
|
permission_module = "PermissionModule"
|
||||||
short_role_name_module = "ShortRoleNameModule"
|
short_role_name_module = "ShortRoleNameModule"
|
||||||
steam_special_offers_module = "SteamSpecialOffersModule"
|
steam_special_offers_module = "SteamSpecialOffersModule"
|
||||||
# features
|
# features
|
||||||
@@ -26,6 +27,3 @@ class FeatureFlagsEnum(Enum):
|
|||||||
short_role_name = "ShortRoleName"
|
short_role_name = "ShortRoleName"
|
||||||
technician_full_access = "TechnicianFullAccess"
|
technician_full_access = "TechnicianFullAccess"
|
||||||
steam_special_offers = "SteamSpecialOffers"
|
steam_special_offers = "SteamSpecialOffers"
|
||||||
scheduled_events = "ScheduledEvents"
|
|
||||||
basic_registration = "BasicRegistration"
|
|
||||||
basic_login = "BasicLogin"
|
|
||||||
|
@@ -16,6 +16,7 @@ class FeatureFlagsSettings(ConfigurationModelABC):
|
|||||||
FeatureFlagsEnum.data_module.value: True, # 03.10.2022 #56
|
FeatureFlagsEnum.data_module.value: True, # 03.10.2022 #56
|
||||||
FeatureFlagsEnum.database_module.value: True, # 02.10.2022 #48
|
FeatureFlagsEnum.database_module.value: True, # 02.10.2022 #48
|
||||||
FeatureFlagsEnum.moderator_module.value: False, # 02.10.2022 #48
|
FeatureFlagsEnum.moderator_module.value: False, # 02.10.2022 #48
|
||||||
|
FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48
|
||||||
FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127
|
FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127
|
||||||
FeatureFlagsEnum.short_role_name_module.value: True, # 28.09.2023 #378
|
FeatureFlagsEnum.short_role_name_module.value: True, # 28.09.2023 #378
|
||||||
FeatureFlagsEnum.steam_special_offers_module.value: True, # 11.10.2023 #188
|
FeatureFlagsEnum.steam_special_offers_module.value: True, # 11.10.2023 #188
|
||||||
@@ -28,9 +29,6 @@ class FeatureFlagsSettings(ConfigurationModelABC):
|
|||||||
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
|
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
|
||||||
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
|
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
|
||||||
FeatureFlagsEnum.steam_special_offers.value: False, # 11.10.2023 #188
|
FeatureFlagsEnum.steam_special_offers.value: False, # 11.10.2023 #188
|
||||||
FeatureFlagsEnum.scheduled_events.value: False, # 14.11.2023 #410
|
|
||||||
FeatureFlagsEnum.basic_registration.value: False, # 19.11.2023 #440
|
|
||||||
FeatureFlagsEnum.basic_login.value: False, # 19.11.2023 #440
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, **kwargs: dict):
|
def __init__(self, **kwargs: dict):
|
||||||
|
@@ -10,7 +10,9 @@ class FileLoggingSettings(LoggingSettings):
|
|||||||
console_log_level: LoggingLevelEnum = None,
|
console_log_level: LoggingLevelEnum = None,
|
||||||
file_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
|
self._key = key
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.core_extension"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -9,7 +9,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.helper.command_checks import CommandChecks
|
from bot_core.helper.command_checks import CommandChecks
|
||||||
from bot_core.helper.event_checks import EventChecks
|
from bot_core.helper.event_checks import EventChecks
|
||||||
from bot_core.abc.permission_service_abc import PermissionServiceABC
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
|
|
||||||
|
|
||||||
class CoreExtension(ApplicationExtensionABC):
|
class CoreExtension(ApplicationExtensionABC):
|
||||||
@@ -17,7 +17,9 @@ class CoreExtension(ApplicationExtensionABC):
|
|||||||
ApplicationExtensionABC.__init__(self)
|
ApplicationExtensionABC.__init__(self)
|
||||||
|
|
||||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
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):
|
if not feature_flags.get_flag(FeatureFlagsEnum.core_module):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@@ -15,8 +15,14 @@ class CoreExtensionModule(ModuleABC):
|
|||||||
def __init__(self, dc: DiscordCollectionABC):
|
def __init__(self, dc: DiscordCollectionABC):
|
||||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_extension_module)
|
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
|
pass
|
||||||
|
|
||||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
def configure_services(
|
||||||
services.add_transient(DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent)
|
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||||
|
):
|
||||||
|
services.add_transient(
|
||||||
|
DiscordEventTypesEnum.on_ready.value, CoreExtensionOnReadyEvent
|
||||||
|
)
|
||||||
|
@@ -1,25 +1,23 @@
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
import asyncio
|
||||||
|
|
||||||
|
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.logging.event_logger import EventLogger
|
|
||||||
|
|
||||||
|
|
||||||
class CoreExtensionOnReadyEvent(OnReadyABC):
|
class CoreExtensionOnReadyEvent(OnReadyABC):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: ConfigurationABC,
|
logger: LoggerABC,
|
||||||
logger: EventLogger,
|
|
||||||
bot: DiscordBotServiceABC,
|
bot: DiscordBotServiceABC,
|
||||||
client_utils: ClientUtilsABC,
|
client_utils: ClientUtilsABC,
|
||||||
t: TranslatePipe,
|
t: TranslatePipe,
|
||||||
):
|
):
|
||||||
OnReadyABC.__init__(self)
|
OnReadyABC.__init__(self)
|
||||||
|
|
||||||
self._config = config
|
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
self._bot = bot
|
self._bot = bot
|
||||||
self._client_utils = client_utils
|
self._client_utils = client_utils
|
||||||
@@ -29,5 +27,5 @@ class CoreExtensionOnReadyEvent(OnReadyABC):
|
|||||||
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
self._logger.debug(__name__, f"Module {type(self)} started")
|
self._logger.debug(__name__, f"Module {type(self)} started")
|
||||||
await self._client_utils.set_maintenance_mode(self._config.get_configuration(MAINTENANCE))
|
await self._client_utils.presence_game("common.presence.running")
|
||||||
self._logger.trace(__name__, f"Module {type(self)} stopped")
|
self._logger.trace(__name__, f"Module {type(self)} stopped")
|
||||||
|
@@ -7,7 +7,6 @@ from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
|||||||
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.module_abc import ModuleABC
|
from bot_core.abc.module_abc import ModuleABC
|
||||||
from bot_core.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||||
from bot_core.events.core_on_ready_event import CoreOnReadyEvent
|
from bot_core.events.core_on_ready_event import CoreOnReadyEvent
|
||||||
from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe
|
from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe
|
||||||
@@ -15,22 +14,24 @@ from bot_core.service.client_utils_service import ClientUtilsService
|
|||||||
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_core.service.message_service import MessageService
|
from bot_core.service.message_service import MessageService
|
||||||
from bot_core.service.permission_service import PermissionService
|
|
||||||
|
|
||||||
|
|
||||||
class CoreModule(ModuleABC):
|
class CoreModule(ModuleABC):
|
||||||
def __init__(self, dc: DiscordCollectionABC):
|
def __init__(self, dc: DiscordCollectionABC):
|
||||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_module)
|
ModuleABC.__init__(self, dc, FeatureFlagsEnum.core_module)
|
||||||
|
|
||||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
def configure_configuration(
|
||||||
|
self, config: ConfigurationABC, env: ApplicationEnvironmentABC
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
def configure_services(
|
||||||
|
self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC
|
||||||
|
):
|
||||||
services.add_transient(ConfigService)
|
services.add_transient(ConfigService)
|
||||||
services.add_transient(MessageServiceABC, MessageService)
|
services.add_transient(MessageServiceABC, MessageService)
|
||||||
services.add_transient(ClientUtilsABC, ClientUtilsService)
|
services.add_transient(ClientUtilsABC, ClientUtilsService)
|
||||||
services.add_transient(DataIntegrityService)
|
services.add_transient(DataIntegrityService)
|
||||||
services.add_singleton(PermissionServiceABC, PermissionService)
|
|
||||||
|
|
||||||
# pipes
|
# pipes
|
||||||
services.add_transient(DateTimeOffsetPipe)
|
services.add_transient(DateTimeOffsetPipe)
|
||||||
|
@@ -1,2 +0,0 @@
|
|||||||
MIGRATION_ONLY = "MIGRATION_ONLY"
|
|
||||||
MAINTENANCE = "MAINTENANCE"
|
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.events"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -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: EventLogger,
|
logger: LoggerABC,
|
||||||
bot: DiscordBotServiceABC,
|
bot: DiscordBotServiceABC,
|
||||||
client_utils: ClientUtilsABC,
|
client_utils: ClientUtilsABC,
|
||||||
t: TranslatePipe,
|
t: TranslatePipe,
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.exception"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.helper"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -7,7 +7,7 @@ from discord.ext.commands import Context
|
|||||||
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.exception.check_error import CheckError
|
from bot_core.exception.check_error import CheckError
|
||||||
from bot_core.abc.permission_service_abc import PermissionServiceABC
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
|
|
||||||
|
|
||||||
class CommandChecks:
|
class CommandChecks:
|
||||||
@@ -44,7 +44,9 @@ class CommandChecks:
|
|||||||
async def check_is_member_admin(ctx: Context):
|
async def check_is_member_admin(ctx: Context):
|
||||||
has_permission = cls._permissions.is_member_admin(ctx.author)
|
has_permission = cls._permissions.is_member_admin(ctx.author)
|
||||||
if not has_permission:
|
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")
|
raise CheckError(f"Member {ctx.author.name} is not admin")
|
||||||
|
|
||||||
return has_permission
|
return has_permission
|
||||||
@@ -56,7 +58,9 @@ class CommandChecks:
|
|||||||
async def check_is_member_technician(ctx: Context):
|
async def check_is_member_technician(ctx: Context):
|
||||||
has_permission = cls._permissions.is_member_technician(ctx.author)
|
has_permission = cls._permissions.is_member_technician(ctx.author)
|
||||||
if not has_permission:
|
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")
|
raise CheckError(f"Member {ctx.author.name} is not technician")
|
||||||
|
|
||||||
return has_permission
|
return has_permission
|
||||||
@@ -68,7 +72,9 @@ class CommandChecks:
|
|||||||
async def check_is_member_moderator(ctx: Context):
|
async def check_is_member_moderator(ctx: Context):
|
||||||
has_permission = cls._permissions.is_member_moderator(ctx.author)
|
has_permission = cls._permissions.is_member_moderator(ctx.author)
|
||||||
if not has_permission:
|
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")
|
raise CheckError(f"Member {ctx.author.name} is not moderator")
|
||||||
|
|
||||||
return has_permission
|
return has_permission
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import inspect
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
@@ -18,18 +17,11 @@ class EventChecks:
|
|||||||
cls._client_utils = client_utils
|
cls._client_utils = client_utils
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def check_is_ready(cls, func):
|
def check_is_ready(cls):
|
||||||
async def check_if_bot_is_ready(*args, **kwargs):
|
async def check_if_bot_is_ready() -> bool:
|
||||||
result = await cls._client_utils.check_if_bot_is_ready_yet()
|
result = await cls._client_utils.check_if_bot_is_ready_yet()
|
||||||
if not result:
|
if not result:
|
||||||
|
raise CheckError(f"Bot is not ready")
|
||||||
|
return result
|
||||||
|
|
||||||
def empty(*args, **kwargs):
|
return commands.check(check_if_bot_is_ready)
|
||||||
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"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports
|
# imports
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
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)
|
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.pipes"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports
|
# imports
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_core.service"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports:
|
# imports:
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -16,7 +16,6 @@ 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.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.environment_variables import MAINTENANCE
|
|
||||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||||
from bot_data.abc.user_joined_voice_channel_repository_abc import (
|
from bot_data.abc.user_joined_voice_channel_repository_abc import (
|
||||||
@@ -63,39 +62,40 @@ class ClientUtilsService(ClientUtilsABC):
|
|||||||
|
|
||||||
def received_command(self, guild_id: int):
|
def received_command(self, guild_id: int):
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
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
|
client.received_command_count += 1
|
||||||
self._clients.update_client(client)
|
self._clients.update_client(client)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
|
|
||||||
def moved_user(self, guild_id: int):
|
def moved_user(self, guild_id: int):
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
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
|
client.moved_users_count += 1
|
||||||
self._clients.update_client(client)
|
self._clients.update_client(client)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
|
|
||||||
def moved_users(self, guild_id: int, count: int):
|
def moved_users(self, guild_id: int, count: int):
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
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
|
client.moved_users_count += count
|
||||||
self._clients.update_client(client)
|
self._clients.update_client(client)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
|
|
||||||
def get_client(self, dc_ic: int, guild_id: int):
|
def get_client(self, dc_ic: int, guild_id: int):
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
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
|
return client
|
||||||
|
|
||||||
async def check_if_bot_is_ready_yet(self) -> bool:
|
async def check_if_bot_is_ready_yet(self) -> bool:
|
||||||
if self._config.get_configuration(MAINTENANCE):
|
if self._config.get_configuration("IS_READY") == "true":
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"Bot is in maintenance mode",
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
if self._config.get_configuration("IS_READY") is True:
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
self._logger.debug(
|
self._logger.debug(
|
||||||
@@ -129,7 +129,9 @@ class ClientUtilsService(ClientUtilsABC):
|
|||||||
await self._bot.change_presence(activity=discord.Game(name=name))
|
await self._bot.change_presence(activity=discord.Game(name=name))
|
||||||
self._logger.info(__name__, f"Set presence {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 current != "":
|
||||||
if select is None:
|
if select is None:
|
||||||
select = lambda x: x
|
select = lambda x: x
|
||||||
@@ -143,15 +145,18 @@ class ClientUtilsService(ClientUtilsABC):
|
|||||||
|
|
||||||
return _l.take(25)
|
return _l.take(25)
|
||||||
|
|
||||||
def update_user_message_xp_count_by_hour(
|
def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour(
|
||||||
self,
|
self,
|
||||||
created_at: datetime,
|
created_at: datetime,
|
||||||
user: User,
|
user: User,
|
||||||
settings: ServerConfig,
|
settings: ServerConfig,
|
||||||
is_reaction: bool = False,
|
is_reaction: bool = False,
|
||||||
):
|
) -> bool:
|
||||||
|
umcph = None
|
||||||
try:
|
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:
|
if umcph is None:
|
||||||
self._umcphs.add_user_message_count_per_hour(
|
self._umcphs.add_user_message_count_per_hour(
|
||||||
UserMessageCountPerHour(
|
UserMessageCountPerHour(
|
||||||
@@ -161,50 +166,50 @@ class ClientUtilsService(ClientUtilsABC):
|
|||||||
user,
|
user,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self._db.save_changes()
|
|
||||||
umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.id, created_at)
|
|
||||||
|
|
||||||
umcph.xp_count += settings.xp_per_reaction if is_reaction else settings.xp_per_message
|
self._db.save_changes()
|
||||||
|
|
||||||
|
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__,
|
||||||
|
f"Cannot add user message count per hour with id {umcph.id}",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
if is_reaction:
|
||||||
|
umcph.xp_count += settings.xp_per_reaction
|
||||||
|
else:
|
||||||
|
umcph.xp_count += settings.xp_per_message
|
||||||
|
|
||||||
self._umcphs.update_user_message_count_per_hour(umcph)
|
self._umcphs.update_user_message_count_per_hour(umcph)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.error(
|
self._logger.error(
|
||||||
__name__,
|
__name__,
|
||||||
f"Cannot update user message count per hour {created_at}",
|
f"Cannot update user message count per hour with id {umcph.id}",
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour(
|
if umcph.xp_count is None:
|
||||||
self,
|
|
||||||
created_at: datetime,
|
|
||||||
user: User,
|
|
||||||
settings: ServerConfig,
|
|
||||||
is_reaction: bool = False,
|
|
||||||
) -> bool:
|
|
||||||
try:
|
|
||||||
umcph = self._umcphs.find_user_message_count_per_hour_by_user_id_and_date(user.id, created_at)
|
|
||||||
if umcph is None or umcph.xp_count is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return umcph.xp_count > settings.max_message_xp_per_hour
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(
|
|
||||||
__name__,
|
|
||||||
f"Cannot add user message count per hour with",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
return umcph.xp_count > settings.max_message_xp_per_hour
|
||||||
|
|
||||||
def get_ontime_for_user(self, user: User) -> float:
|
def get_ontime_for_user(self, user: User) -> float:
|
||||||
return round(
|
return round(
|
||||||
sum(
|
self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(
|
||||||
[
|
user.id
|
||||||
(join.leaved_on - join.joined_on).total_seconds() / 3600
|
)
|
||||||
for join in 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)
|
||||||
if join.leaved_on is not None and join.joined_on is not None
|
.sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600),
|
||||||
]
|
|
||||||
),
|
|
||||||
2,
|
2,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -219,7 +224,11 @@ class ClientUtilsService(ClientUtilsABC):
|
|||||||
guild: Guild = self._bot.guilds.where(lambda g: g == guild).single()
|
guild: Guild = self._bot.guilds.where(lambda g: g == guild).single()
|
||||||
channel = guild.get_channel(discord_channel_id)
|
channel = guild.get_channel(discord_channel_id)
|
||||||
message = await channel.fetch_message(discord_message_id)
|
message = await channel.fetch_message(discord_message_id)
|
||||||
emoji = List(discord.Emoji, [x for x in guild.emojis if 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:
|
if emoji is None:
|
||||||
self._logger.debug(__name__, f"Emoji {rule.emoji_name} not found")
|
self._logger.debug(__name__, f"Emoji {rule.emoji_name} not found")
|
||||||
@@ -239,7 +248,9 @@ class ClientUtilsService(ClientUtilsABC):
|
|||||||
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
||||||
try:
|
try:
|
||||||
server = self._servers.get_server_by_discord_id(member.guild.id)
|
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:
|
if settings.default_role_id is None:
|
||||||
return
|
return
|
||||||
@@ -251,11 +262,6 @@ class ClientUtilsService(ClientUtilsABC):
|
|||||||
await member.add_roles(default_role)
|
await member.add_roles(default_role)
|
||||||
|
|
||||||
except Exception as e:
|
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,7 +7,6 @@ from bot_data.abc.technician_config_repository_abc import TechnicianConfigReposi
|
|||||||
from bot_data.model.server import Server
|
from bot_data.model.server import Server
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
from bot_data.model.technician_config import TechnicianConfig
|
||||||
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
||||||
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigService:
|
class ConfigService:
|
||||||
@@ -17,24 +16,17 @@ class ConfigService:
|
|||||||
services: ServiceProviderABC,
|
services: ServiceProviderABC,
|
||||||
technician_config_repo: TechnicianConfigRepositoryABC,
|
technician_config_repo: TechnicianConfigRepositoryABC,
|
||||||
server_config_repo: ServerConfigRepositoryABC,
|
server_config_repo: ServerConfigRepositoryABC,
|
||||||
technician_seeder: TechnicianConfigSeeder,
|
|
||||||
server_seeder: ServerConfigSeeder,
|
server_seeder: ServerConfigSeeder,
|
||||||
):
|
):
|
||||||
self._config = config
|
self._config = config
|
||||||
self._services = services
|
self._services = services
|
||||||
self._technician_config_repo = technician_config_repo
|
self._technician_config_repo = technician_config_repo
|
||||||
self._technician_seeder = technician_seeder
|
|
||||||
self._server_config_repo = server_config_repo
|
self._server_config_repo = server_config_repo
|
||||||
|
|
||||||
self._server_seeder = server_seeder
|
self._server_seeder = server_seeder
|
||||||
|
|
||||||
async def reload_technician_config(self):
|
def reload_technician_config(self):
|
||||||
try:
|
technician_config = self._technician_config_repo.get_technician_config()
|
||||||
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(TechnicianConfig, technician_config)
|
||||||
self._config.add_configuration(
|
self._config.add_configuration(
|
||||||
FeatureFlagsSettings,
|
FeatureFlagsSettings,
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
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_discord.container import Member, Guild
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
||||||
@@ -65,255 +66,410 @@ class DataIntegrityService:
|
|||||||
|
|
||||||
self._is_for_shutdown = False
|
self._is_for_shutdown = False
|
||||||
|
|
||||||
async def check_data_integrity(self, is_for_shutdown=False):
|
def _check_known_users(self):
|
||||||
self._logger.info(__name__, f"Data integrity service started")
|
self._logger.debug(
|
||||||
if is_for_shutdown != self._is_for_shutdown:
|
__name__, f"Start checking KnownUsers table, {len(self._bot.users)}"
|
||||||
self._is_for_shutdown = is_for_shutdown
|
)
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
user = self._known_users.find_user_by_discord_id(u.id)
|
||||||
for g in self._bot.guilds:
|
if user is not None:
|
||||||
self._logger.debug(__name__, f"Start check for server: {g.id}")
|
continue
|
||||||
s = self._get_or_create_server(g)
|
|
||||||
self._logger.debug(__name__, f"Start check for clients")
|
|
||||||
self._check_clients(g.id, s)
|
|
||||||
|
|
||||||
for m in [m for m in g.members if not m.bot]:
|
self._logger.warn(__name__, f"Unknown user: {u.id}")
|
||||||
await self._check_default_role(m)
|
self._logger.debug(__name__, f"Add user: {u.id}")
|
||||||
self._check_known_user(m.id)
|
self._known_users.add_user(KnownUser(u.id))
|
||||||
|
self._db_context.save_changes()
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Start check for member: {g.id}@{m.id}")
|
user = self._known_users.find_user_by_discord_id(u.id)
|
||||||
u = self._get_or_create_user(s, m.id)
|
if user is None:
|
||||||
|
self._logger.fatal(__name__, f"Cannot add user: {u.id}")
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Start check for user joined server: {g.id}@{m.id}")
|
self._logger.debug(__name__, f"Added user: {u.id}")
|
||||||
self._check_user_join(g, m, u)
|
except Exception as e:
|
||||||
|
self._logger.error(__name__, f"Cannot get user", e)
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Start check for user joined voice channels: {g.id}@{m.id}")
|
def _check_servers(self):
|
||||||
self._check_user_joined_vc(g.id, m, u)
|
self._logger.debug(__name__, f"Start checking Servers table")
|
||||||
|
for g in self._bot.guilds:
|
||||||
|
g: discord.Guild = g
|
||||||
|
try:
|
||||||
|
server = self._servers.find_server_by_discord_id(g.id)
|
||||||
|
if server is not None:
|
||||||
|
continue
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Start check for user joined game servers: {g.id}@{m.id}")
|
self._logger.warn(__name__, f"Server not found in database: {g.id}")
|
||||||
self._check_user_joined_gs(g.id, m.id, u)
|
self._logger.debug(__name__, f"Add server: {g.id}")
|
||||||
|
self._servers.add_server(Server(g.id))
|
||||||
|
self._db_context.save_changes()
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Start check for user got achievements: {g.id}@{m.id}")
|
server = self._servers.find_server_by_discord_id(g.id)
|
||||||
await self._check_for_user_achievements(u)
|
if server is None:
|
||||||
|
self._logger.fatal(__name__, f"Cannot add server: {g.id}")
|
||||||
|
|
||||||
for m in [m for m in g.members if m.bot]:
|
self._logger.debug(__name__, f"Added server: {g.id}")
|
||||||
u = self._users.find_user_by_discord_id_and_server_id(m.id, s.id)
|
except Exception as e:
|
||||||
if u is None:
|
self._logger.error(__name__, f"Cannot get server", e)
|
||||||
continue
|
|
||||||
|
|
||||||
self._remove_bot(u)
|
|
||||||
self._logger.info(__name__, f"Data integrity service finished")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.fatal(__name__, f"Checking data integrity failed", e)
|
|
||||||
|
|
||||||
def _get_or_create_server(self, guild: Guild) -> Server:
|
|
||||||
try:
|
|
||||||
server = self._servers.find_server_by_discord_id(guild.id)
|
|
||||||
if server is not None:
|
|
||||||
return server
|
|
||||||
|
|
||||||
self._logger.warn(__name__, f"Server not found in database: {guild.id}")
|
|
||||||
self._logger.debug(__name__, f"Add server: {guild.id}")
|
|
||||||
self._servers.add_server(Server(guild.id))
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
server = self._servers.find_server_by_discord_id(guild.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Cannot add server: {guild.id}")
|
|
||||||
|
|
||||||
self._logger.trace(__name__, f"Added server: {guild.id}")
|
|
||||||
return server
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get server", e)
|
|
||||||
|
|
||||||
def _check_clients(self, guild_id: int, server: Server):
|
|
||||||
try:
|
|
||||||
client = self._clients.find_client_by_server_id(server.id)
|
|
||||||
if client is not None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"Client for server {guild_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._db_context.save_changes()
|
|
||||||
|
|
||||||
client = self._clients.find_client_by_server_id(server.id)
|
|
||||||
if client is None:
|
|
||||||
self._logger.fatal(
|
|
||||||
__name__,
|
|
||||||
f"Cannot add client {self._bot.user.id} for server {guild_id}",
|
|
||||||
)
|
|
||||||
|
|
||||||
self._logger.trace(__name__, f"Added client: {guild_id}")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get client", e)
|
|
||||||
|
|
||||||
results = self._servers.get_servers()
|
results = self._servers.get_servers()
|
||||||
if results is None or len(results) == 0:
|
if results is None or len(results) == 0:
|
||||||
self._logger.error(__name__, f"Table Servers is empty!")
|
self._logger.error(__name__, f"Table Servers is empty!")
|
||||||
|
|
||||||
def _check_known_user(self, member_id: int):
|
def _check_clients(self):
|
||||||
try:
|
self._logger.debug(__name__, f"Start checking Clients table")
|
||||||
if self._known_users.find_user_by_discord_id(member_id) is not None:
|
for g in self._bot.guilds:
|
||||||
return
|
g: discord.Guild = g
|
||||||
|
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.warn(__name__, f"Unknown user: {member_id}")
|
client = self._clients.find_client_by_server_id(server.id)
|
||||||
self._logger.trace(__name__, f"Add known user: {member_id}")
|
if client is not None:
|
||||||
self._known_users.add_user(KnownUser(member_id))
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
user = self._known_users.find_user_by_discord_id(member_id)
|
|
||||||
if user is None:
|
|
||||||
self._logger.fatal(__name__, f"Cannot add user: {member_id}")
|
|
||||||
|
|
||||||
self._logger.trace(__name__, f"Added known user: {member_id}")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get user", e)
|
|
||||||
|
|
||||||
def _get_or_create_user(self, server: Server, member_id: int) -> User:
|
|
||||||
try:
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(member_id, server.id)
|
|
||||||
if user is not None:
|
|
||||||
return user
|
|
||||||
|
|
||||||
self._logger.warn(__name__, f"User not found in database: {member_id}")
|
|
||||||
self._logger.debug(__name__, f"Add user: {member_id}")
|
|
||||||
self._users.add_user(User(member_id, 0, 0, 0, None, server))
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
self._logger.trace(__name__, f"Added User: {member_id}")
|
|
||||||
return self._users.get_user_by_discord_id_and_server_id(member_id, server.id)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get User", e)
|
|
||||||
|
|
||||||
results = self._users.get_users()
|
|
||||||
if results is None or len(results) == 0:
|
|
||||||
self._logger.error(__name__, f"Table Users is empty!")
|
|
||||||
|
|
||||||
def _check_user_join(self, guild: Guild, member: Member, user: User):
|
|
||||||
try:
|
|
||||||
join = self._user_joins.find_active_user_joined_server_by_user_id(user.id)
|
|
||||||
if join is not None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"Active UserJoinedServer not found in database: {guild.id}:{member.id}@{member.joined_at}",
|
|
||||||
)
|
|
||||||
self._logger.debug(
|
|
||||||
__name__,
|
|
||||||
f"Add UserJoinedServer: {guild.id}:{member.id}@{member.joined_at}",
|
|
||||||
)
|
|
||||||
self._user_joins.add_user_joined_server(UserJoinedServer(user, self._dtp.transform(member.joined_at), None))
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
self._logger.trace(__name__, f"Added UserJoinedServer: {member.id}")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get UserJoinedServer", e)
|
|
||||||
|
|
||||||
try:
|
|
||||||
joins = self._user_joins.get_user_joined_servers()
|
|
||||||
for join in [x for x in joins if x.user.server.discord_id == guild.id and x.leaved_on is None]:
|
|
||||||
dc_user = guild.get_member(join.user.discord_id)
|
|
||||||
if dc_user is not None:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self._logger.warn(
|
self._logger.warn(
|
||||||
__name__,
|
__name__,
|
||||||
f"User {join.user.discord_id} already left the server.",
|
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)
|
||||||
)
|
)
|
||||||
join.leaved_on = datetime.now()
|
|
||||||
self._user_joins.update_user_joined_server(join)
|
|
||||||
|
|
||||||
self._db_context.save_changes()
|
self._db_context.save_changes()
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot update UserJoinedServer", e)
|
|
||||||
|
|
||||||
def _check_user_joined_vc(self, guild_id: int, member: Member, user: User):
|
client = self._clients.find_client_by_server_id(server.id)
|
||||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
|
if client is None:
|
||||||
|
self._logger.fatal(
|
||||||
|
__name__,
|
||||||
|
f"Cannot add client {self._bot.user.id} for server {g.id}",
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
self._logger.debug(__name__, f"Added client: {g.id}")
|
||||||
# close open voice states
|
except Exception as e:
|
||||||
joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.id)
|
self._logger.error(__name__, f"Cannot get client", e)
|
||||||
if joins is None or len(joins) == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
|
results = self._servers.get_servers()
|
||||||
|
if results is None or len(results) == 0:
|
||||||
|
self._logger.error(__name__, f"Table Servers is empty!")
|
||||||
|
|
||||||
|
def _check_users(self):
|
||||||
|
self._logger.debug(__name__, f"Start checking Users table")
|
||||||
|
for g in self._bot.guilds:
|
||||||
|
g: discord.Guild = g
|
||||||
|
|
||||||
|
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}"
|
||||||
|
)
|
||||||
|
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
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._db_context.save_changes()
|
||||||
|
|
||||||
|
self._logger.debug(__name__, f"Added User: {u.id}")
|
||||||
|
except Exception as e:
|
||||||
|
self._logger.error(__name__, f"Cannot get User", e)
|
||||||
|
|
||||||
|
results = self._users.get_users()
|
||||||
|
if results is None or len(results) == 0:
|
||||||
|
self._logger.error(__name__, f"Table Users is empty!")
|
||||||
|
|
||||||
|
def _check_user_joins(self):
|
||||||
|
self._logger.debug(__name__, f"Start checking UserJoinedServers table")
|
||||||
|
for guild in self._bot.guilds:
|
||||||
|
guild: discord.Guild = guild
|
||||||
|
|
||||||
|
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}"
|
||||||
|
)
|
||||||
|
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
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}"
|
||||||
|
)
|
||||||
|
|
||||||
|
join = self._user_joins.find_active_user_joined_server_by_user_id(
|
||||||
|
user.id
|
||||||
|
)
|
||||||
|
if join is not None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
m: discord.Member = u
|
||||||
|
self._logger.warn(
|
||||||
|
__name__,
|
||||||
|
f"Active UserJoinedServer not found in database: {guild.id}:{u.id}@{m.joined_at}",
|
||||||
|
)
|
||||||
|
self._logger.debug(
|
||||||
|
__name__,
|
||||||
|
f"Add UserJoinedServer: {guild.id}:{u.id}@{m.joined_at}",
|
||||||
|
)
|
||||||
|
self._user_joins.add_user_joined_server(
|
||||||
|
UserJoinedServer(user, self._dtp.transform(m.joined_at), None)
|
||||||
|
)
|
||||||
|
self._db_context.save_changes()
|
||||||
|
|
||||||
|
self._logger.debug(__name__, f"Added UserJoinedServer: {u.id}")
|
||||||
|
except Exception as e:
|
||||||
|
self._logger.error(__name__, f"Cannot get UserJoinedServer", e)
|
||||||
|
|
||||||
|
results = self._users.get_users()
|
||||||
|
if results is None or len(results) == 0:
|
||||||
|
self._logger.error(__name__, f"Table Users is empty!")
|
||||||
|
|
||||||
|
joins = self._user_joins.get_user_joined_servers()
|
||||||
for join in joins:
|
for join in joins:
|
||||||
self._logger.warn(
|
join: UserJoinedServer = join
|
||||||
__name__,
|
if join.user.server.discord_id != guild.id:
|
||||||
f"Active UserJoinedVoiceChannel found in database: {guild_id}:{member.id}@{join.joined_on}",
|
continue
|
||||||
)
|
|
||||||
join.leaved_on = datetime.now()
|
|
||||||
|
|
||||||
if ((join.leaved_on - join.joined_on).total_seconds() / 60 / 60) > settings.max_voice_state_hours:
|
if join.leaved_on is not None:
|
||||||
join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours)
|
continue
|
||||||
|
|
||||||
self._user_joins_vc.update_user_joined_voice_channel(join)
|
dc_user = guild.get_member(join.user.discord_id)
|
||||||
|
if dc_user is None:
|
||||||
|
self._logger.warn(
|
||||||
|
__name__,
|
||||||
|
f"User {join.user.discord_id} already left the server.",
|
||||||
|
)
|
||||||
|
join.leaved_on = datetime.now()
|
||||||
|
self._user_joins.update_user_joined_server(join)
|
||||||
|
|
||||||
if self._is_for_shutdown:
|
|
||||||
user.xp += round(join.time * settings.xp_per_ontime_hour)
|
|
||||||
self._users.update_user(user)
|
|
||||||
|
|
||||||
self._db_context.save_changes()
|
|
||||||
if self._is_for_shutdown:
|
|
||||||
return
|
|
||||||
|
|
||||||
# add open voice states
|
|
||||||
if member.voice is None or member.voice.channel.id in settings.afk_channel_ids:
|
|
||||||
return
|
|
||||||
|
|
||||||
join = UserJoinedVoiceChannel(user, member.voice.channel.id, datetime.now())
|
|
||||||
self._user_joins_vc.add_user_joined_voice_channel(join)
|
|
||||||
self._db_context.save_changes()
|
self._db_context.save_changes()
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e)
|
|
||||||
|
|
||||||
def _check_user_joined_gs(self, guild_id: int, member_id: int, user: User):
|
def _check_user_joins_vc(self):
|
||||||
try:
|
self._logger.debug(__name__, f"Start checking UserJoinedVoiceChannel table")
|
||||||
joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.id)
|
for guild in self._bot.guilds:
|
||||||
if joins is None or len(joins) == 0:
|
guild: discord.Guild = guild
|
||||||
return
|
settings: ServerConfig = self._config.get_configuration(
|
||||||
|
f"ServerConfig_{guild.id}"
|
||||||
|
)
|
||||||
|
|
||||||
for join in joins:
|
server = self._servers.find_server_by_discord_id(guild.id)
|
||||||
self._logger.warn(
|
if server is None:
|
||||||
__name__,
|
self._logger.fatal(
|
||||||
f"Active UserJoinedGameServer found in database: {guild_id}:{member_id}@{join.joined_on}",
|
__name__, f"Server not found in database: {guild.id}"
|
||||||
)
|
)
|
||||||
join.leaved_on = datetime.now()
|
|
||||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
|
|
||||||
|
|
||||||
if join.time > settings.max_voice_state_hours:
|
try:
|
||||||
join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours)
|
# 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"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
self._user_joined_gs.update_user_joined_game_server(join)
|
user = self._users.find_user_by_discord_id_and_server_id(
|
||||||
if self._is_for_shutdown:
|
member.id, server.id
|
||||||
user.xp += round(join.time * settings.xp_per_ontime_hour)
|
)
|
||||||
self._users.update_user(user)
|
if user is None:
|
||||||
|
self._logger.fatal(
|
||||||
|
__name__, f"User not found in database: {member.id}"
|
||||||
|
)
|
||||||
|
|
||||||
self._db_context.save_changes()
|
joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(
|
||||||
except Exception as e:
|
user.id
|
||||||
self._logger.error(__name__, f"Cannot get UserJoinedGameServer", e)
|
)
|
||||||
|
if joins is None or len(joins) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
async def _check_for_user_achievements(self, user: User):
|
for join in joins:
|
||||||
try:
|
self._logger.warn(
|
||||||
await self._achievements.validate_achievements_for_user(user)
|
__name__,
|
||||||
except Exception as e:
|
f"Active UserJoinedVoiceChannel found in database: {guild.id}:{member.id}@{join.joined_on}",
|
||||||
self._logger.error(__name__, f"Cannot check UserGotAchievement for {user.id}", e)
|
)
|
||||||
|
join.leaved_on = datetime.now()
|
||||||
|
|
||||||
async def _check_default_role(self, member: Member):
|
if (
|
||||||
await self._client_utils.check_default_role(member)
|
(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
|
||||||
|
)
|
||||||
|
|
||||||
def _remove_bot(self, user: User):
|
self._user_joins_vc.update_user_joined_voice_channel(join)
|
||||||
known_user = self._known_users.find_user_by_discord_id(user.discord_id)
|
|
||||||
if known_user is not None:
|
|
||||||
self._known_users.delete_user(known_user)
|
|
||||||
|
|
||||||
for join in self._user_joins.get_user_joined_servers_by_user_id(user.id):
|
if self._is_for_shutdown:
|
||||||
self._user_joins.delete_user_joined_server(join)
|
user.xp += round(join.time * settings.xp_per_ontime_hour)
|
||||||
|
self._users.update_user(user)
|
||||||
|
|
||||||
self._user_joins_vc.delete_user_joined_voice_channel_by_user_id(user.id)
|
self._db_context.save_changes()
|
||||||
self._users.delete_user(user)
|
if self._is_for_shutdown:
|
||||||
self._db_context.save_changes()
|
return
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
if user is None:
|
||||||
|
self._logger.fatal(
|
||||||
|
__name__, f"User not found in database: {member.id}"
|
||||||
|
)
|
||||||
|
|
||||||
|
join = UserJoinedVoiceChannel(
|
||||||
|
user, member.voice.channel.id, datetime.now()
|
||||||
|
)
|
||||||
|
self._user_joins_vc.add_user_joined_voice_channel(join)
|
||||||
|
self._db_context.save_changes()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e)
|
||||||
|
|
||||||
|
def _check_user_joined_gs(self):
|
||||||
|
self._logger.debug(__name__, f"Start checking UserJoinedGameServer table")
|
||||||
|
for guild in self._bot.guilds:
|
||||||
|
guild: discord.Guild = guild
|
||||||
|
|
||||||
|
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}"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
for member in guild.members:
|
||||||
|
if member.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
|
||||||
|
)
|
||||||
|
if user is None:
|
||||||
|
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
|
||||||
|
)
|
||||||
|
if joins is None or len(joins) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for join in joins:
|
||||||
|
self._logger.warn(
|
||||||
|
__name__,
|
||||||
|
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}"
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
self._user_joined_gs.update_user_joined_game_server(join)
|
||||||
|
if self._is_for_shutdown:
|
||||||
|
user.xp += round(join.time * settings.xp_per_ontime_hour)
|
||||||
|
self._users.update_user(user)
|
||||||
|
|
||||||
|
self._db_context.save_changes()
|
||||||
|
except Exception as e:
|
||||||
|
self._logger.error(__name__, f"Cannot get UserJoinedGameServer", e)
|
||||||
|
|
||||||
|
async def _check_for_user_achievements(self):
|
||||||
|
self._logger.debug(__name__, f"Start checking UserGotAchievement table")
|
||||||
|
|
||||||
|
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}"
|
||||||
|
)
|
||||||
|
|
||||||
|
for member in guild.members:
|
||||||
|
if member.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
|
||||||
|
)
|
||||||
|
if user is None:
|
||||||
|
self._logger.fatal(
|
||||||
|
__name__, f"User not found in database: {member.id}"
|
||||||
|
)
|
||||||
|
|
||||||
|
await self._achievements.validate_achievements_for_user(user)
|
||||||
|
|
||||||
|
async def _check_default_role(self):
|
||||||
|
for guild in self._bot.guilds:
|
||||||
|
for member in guild.members:
|
||||||
|
await self._client_utils.check_default_role(member)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
await self._check_default_role()
|
||||||
|
self._check_known_users()
|
||||||
|
self._check_servers()
|
||||||
|
self._check_clients()
|
||||||
|
self._check_users()
|
||||||
|
self._check_user_joins()
|
||||||
|
self._check_user_joins_vc()
|
||||||
|
self._check_user_joined_gs()
|
||||||
|
await self._check_for_user_achievements()
|
||||||
|
@@ -31,15 +31,23 @@ class MessageService(MessageServiceABC):
|
|||||||
self._clients = clients
|
self._clients = clients
|
||||||
self._db = db
|
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")
|
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)
|
await asyncio.sleep(server_st.message_delete_timer)
|
||||||
for message in messages:
|
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")
|
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 = (
|
guild_id = (
|
||||||
message.guild.id
|
message.guild.id
|
||||||
if message.guild is not None
|
if message.guild is not None
|
||||||
@@ -50,7 +58,9 @@ class MessageService(MessageServiceABC):
|
|||||||
else None
|
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:
|
if not mass_delete:
|
||||||
await asyncio.sleep(server_st.message_delete_timer)
|
await asyncio.sleep(server_st.message_delete_timer)
|
||||||
self._logger.debug(
|
self._logger.debug(
|
||||||
@@ -64,7 +74,9 @@ class MessageService(MessageServiceABC):
|
|||||||
self._logger.error(__name__, f"Deleting message failed", e)
|
self._logger.error(__name__, f"Deleting message failed", e)
|
||||||
else:
|
else:
|
||||||
if not without_tracking:
|
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._db.save_changes()
|
||||||
self._logger.info(__name__, f"Deleted message {message}")
|
self._logger.info(__name__, f"Deleted message {message}")
|
||||||
|
|
||||||
@@ -76,7 +88,9 @@ class MessageService(MessageServiceABC):
|
|||||||
wait_before_delete: int = None,
|
wait_before_delete: int = None,
|
||||||
without_tracking=False,
|
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
|
msg = None
|
||||||
try:
|
try:
|
||||||
if isinstance(message, discord.Embed):
|
if isinstance(message, discord.Embed):
|
||||||
@@ -86,11 +100,15 @@ class MessageService(MessageServiceABC):
|
|||||||
else:
|
else:
|
||||||
msg = await channel.send(message)
|
msg = await channel.send(message)
|
||||||
except Exception as e:
|
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:
|
else:
|
||||||
self._logger.info(__name__, f"Sent message to channel {channel.id}")
|
self._logger.info(__name__, f"Sent message to channel {channel.id}")
|
||||||
if not without_tracking:
|
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()
|
self._db.save_changes()
|
||||||
|
|
||||||
if wait_before_delete is not None:
|
if wait_before_delete is not None:
|
||||||
@@ -107,17 +125,23 @@ class MessageService(MessageServiceABC):
|
|||||||
receiver: Union[discord.User, discord.Member],
|
receiver: Union[discord.User, discord.Member],
|
||||||
without_tracking=False,
|
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:
|
try:
|
||||||
if isinstance(message, discord.Embed):
|
if isinstance(message, discord.Embed):
|
||||||
msg = await receiver.send(embed=message)
|
msg = await receiver.send(embed=message)
|
||||||
else:
|
else:
|
||||||
msg = await receiver.send(message)
|
msg = await receiver.send(message)
|
||||||
except Exception as e:
|
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:
|
else:
|
||||||
if not without_tracking:
|
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._db.save_changes()
|
||||||
self._logger.info(__name__, f"Sent message to user {receiver.id}")
|
self._logger.info(__name__, f"Sent message to user {receiver.id}")
|
||||||
|
|
||||||
@@ -136,7 +160,9 @@ class MessageService(MessageServiceABC):
|
|||||||
self._logger.debug(__name__, f"Message: {message}")
|
self._logger.debug(__name__, f"Message: {message}")
|
||||||
return None
|
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
|
msg = None
|
||||||
try:
|
try:
|
||||||
if isinstance(message, discord.Embed):
|
if isinstance(message, discord.Embed):
|
||||||
@@ -144,11 +170,15 @@ class MessageService(MessageServiceABC):
|
|||||||
else:
|
else:
|
||||||
msg = await ctx.send(message, file=file, ephemeral=not is_public)
|
msg = await ctx.send(message, file=file, ephemeral=not is_public)
|
||||||
except Exception as e:
|
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:
|
else:
|
||||||
self._logger.info(__name__, f"Sent message to channel {ctx.channel.id}")
|
self._logger.info(__name__, f"Sent message to channel {ctx.channel.id}")
|
||||||
if not without_tracking and ctx.guild is not None:
|
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()
|
self._db.save_changes()
|
||||||
|
|
||||||
if wait_before_delete is not None:
|
if wait_before_delete is not None:
|
||||||
@@ -177,18 +207,30 @@ class MessageService(MessageServiceABC):
|
|||||||
self._logger.debug(__name__, f"Message: {message}")
|
self._logger.debug(__name__, f"Message: {message}")
|
||||||
return
|
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:
|
try:
|
||||||
if isinstance(message, discord.Embed):
|
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:
|
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:
|
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:
|
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:
|
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()
|
self._db.save_changes()
|
||||||
|
|
||||||
if wait_before_delete is not None:
|
if wait_before_delete is not None:
|
||||||
@@ -197,4 +239,6 @@ class MessageService(MessageServiceABC):
|
|||||||
if is_persistent:
|
if is_persistent:
|
||||||
return
|
return
|
||||||
|
|
||||||
await self.delete_message(await interaction.original_response(), without_tracking)
|
await self.delete_message(
|
||||||
|
await interaction.original_response(), without_tracking
|
||||||
|
)
|
||||||
|
@@ -1,114 +0,0 @@
|
|||||||
from typing import Optional
|
|
||||||
|
|
||||||
import discord
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.logging import LoggerABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
|
|
||||||
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
|
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
|
||||||
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
|
|
||||||
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
|
|
||||||
from bot_core.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
|
|
||||||
|
|
||||||
class PermissionService(PermissionServiceABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
logger: LoggerABC,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
servers: ServerRepositoryABC,
|
|
||||||
server_configs: ServerConfigRepositoryABC,
|
|
||||||
technician_configs: TechnicianConfigRepositoryABC,
|
|
||||||
):
|
|
||||||
PermissionServiceABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._bot = bot
|
|
||||||
self._config = config
|
|
||||||
self._servers = servers
|
|
||||||
self._server_configs = server_configs
|
|
||||||
self._technician_configs = technician_configs
|
|
||||||
|
|
||||||
# member_id: {team_member_type: {guild_id: bool}}
|
|
||||||
self._cache: dict[int, dict[TeamMemberTypeEnum, dict[int, bool]]] = {}
|
|
||||||
|
|
||||||
def reset_cache(self):
|
|
||||||
self._cache = {}
|
|
||||||
|
|
||||||
def get_cached_permission(
|
|
||||||
self, member_id: int, team_member_type: TeamMemberTypeEnum, guild_id: int = None
|
|
||||||
) -> Optional[bool]:
|
|
||||||
if member_id not in self._cache:
|
|
||||||
self._cache[member_id] = {}
|
|
||||||
|
|
||||||
if team_member_type not in self._cache[member_id]:
|
|
||||||
self._cache[member_id][team_member_type] = {}
|
|
||||||
return None
|
|
||||||
|
|
||||||
if guild_id not in self._cache[member_id][team_member_type]:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return self._cache[member_id][team_member_type][guild_id]
|
|
||||||
|
|
||||||
def set_cached_permission(
|
|
||||||
self, value: bool, member_id: int, team_member_type: TeamMemberTypeEnum, guild_id: int = None
|
|
||||||
):
|
|
||||||
if member_id not in self._cache:
|
|
||||||
self._cache[member_id] = {}
|
|
||||||
|
|
||||||
if team_member_type not in self._cache[member_id]:
|
|
||||||
self._cache[member_id][team_member_type] = {}
|
|
||||||
|
|
||||||
self._cache[member_id][team_member_type][guild_id] = value
|
|
||||||
|
|
||||||
def _has_member_role(self, member: discord.Member, team_member_type: TeamMemberTypeEnum) -> bool:
|
|
||||||
if member is None or member.guild is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
has_permission_cached = self.get_cached_permission(member.id, team_member_type, member.guild.id)
|
|
||||||
if has_permission_cached is not None:
|
|
||||||
return has_permission_cached
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Checking is member {member.name} {team_member_type.value}")
|
|
||||||
|
|
||||||
has_permission = True in [
|
|
||||||
member.guild.get_role(x.role_id) in member.roles
|
|
||||||
for x in self._server_configs.get_server_config_by_server(
|
|
||||||
self._servers.get_server_by_discord_id(member.guild.id).id
|
|
||||||
).team_role_ids
|
|
||||||
if x.team_member_type == team_member_type
|
|
||||||
]
|
|
||||||
self.set_cached_permission(has_permission, member.id, team_member_type, member.guild.id)
|
|
||||||
return has_permission
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, "Permission check failed", e)
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def is_member_admin(self, member: discord.Member) -> bool:
|
|
||||||
return self._has_member_role(member, TeamMemberTypeEnum.admin)
|
|
||||||
|
|
||||||
def is_member_moderator(self, member: discord.Member) -> bool:
|
|
||||||
return self._has_member_role(member, TeamMemberTypeEnum.moderator) or self._has_member_role(
|
|
||||||
member, TeamMemberTypeEnum.admin
|
|
||||||
)
|
|
||||||
|
|
||||||
def is_member_technician(self, member: discord.Member) -> bool:
|
|
||||||
if member is None or member.guild is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
has_permission_cached = self.get_cached_permission(member.id, TeamMemberTypeEnum.technician)
|
|
||||||
if has_permission_cached is not None:
|
|
||||||
return has_permission_cached
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Checking is member {member.name} technician")
|
|
||||||
|
|
||||||
try:
|
|
||||||
has_permission = member.id in self._technician_configs.get_technician_config().technician_ids
|
|
||||||
self.set_cached_permission(has_permission, member.id, TeamMemberTypeEnum.technician)
|
|
||||||
return has_permission
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, "Permission check failed", e)
|
|
||||||
return False
|
|
@@ -15,7 +15,7 @@ __title__ = "bot_data"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports
|
# imports
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -15,7 +15,7 @@ __title__ = "bot_data.abc"
|
|||||||
__author__ = "Sven Heidemann"
|
__author__ = "Sven Heidemann"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
||||||
__version__ = "1.2.5"
|
__version__ = "1.2.0"
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@ from collections import namedtuple
|
|||||||
# imports
|
# imports
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="5")
|
version_info = VersionInfo(major="1", minor="2", micro="0")
|
||||||
|
@@ -28,7 +28,9 @@ class AchievementRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -23,7 +23,9 @@ class AuthUserRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_filtered_auth_users(self, criteria: AuthUserSelectCriteria) -> FilteredResult:
|
def get_filtered_auth_users(
|
||||||
|
self, criteria: AuthUserSelectCriteria
|
||||||
|
) -> FilteredResult:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -36,7 +36,9 @@ class ClientRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.scheduled_event import ScheduledEvent
|
|
||||||
|
|
||||||
|
|
||||||
class ScheduledEventRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_scheduled_events(self) -> List[ScheduledEvent]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_scheduled_event_by_id(self, id: int) -> ScheduledEvent:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_scheduled_events_by_server_id(self, id: int) -> List[ScheduledEvent]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_scheduled_event(self, scheduled_event: ScheduledEvent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_scheduled_event(self, scheduled_event: ScheduledEvent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_scheduled_event(self, scheduled_event: ScheduledEvent):
|
|
||||||
pass
|
|
@@ -35,25 +35,37 @@ class ServerConfigRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def add_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
def add_server_afk_channel_config(
|
||||||
|
self, server_afk_channel: ServerAFKChannelIdsConfig
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def update_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
def update_server_afk_channel_config(
|
||||||
|
self, server_afk_channel: ServerAFKChannelIdsConfig
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def delete_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
def delete_server_afk_channel_config(
|
||||||
|
self, server_afk_channel: ServerAFKChannelIdsConfig
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
@@ -43,13 +43,19 @@ class TechnicianConfigRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def add_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
def add_technician_ping_url_config(
|
||||||
|
self, technician_ping_url: TechnicianPingUrlConfig
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def update_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
def update_technician_ping_url_config(
|
||||||
|
self, technician_ping_url: TechnicianPingUrlConfig
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def delete_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
def delete_technician_ping_url_config(
|
||||||
|
self, technician_ping_url: TechnicianPingUrlConfig
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
@@ -20,31 +20,45 @@ class UserJoinedGameServerRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -20,15 +20,25 @@ class UserJoinedServerRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_user_joined_servers_by_user_id(self, user_id: int) -> list[UserJoinedServer]:
|
def get_user_joined_server_by_server_id(self, server_id: int) -> UserJoinedServer:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_active_user_joined_server_by_user_id(self, user_id: int) -> UserJoinedServer:
|
def get_user_joined_servers_by_user_id(
|
||||||
|
self, user_id: int
|
||||||
|
) -> list[UserJoinedServer]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def find_active_user_joined_server_by_user_id(self, user_id: int) -> Optional[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]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -19,31 +19,45 @@ class UserJoinedVoiceChannelRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -17,7 +17,9 @@ class UserMessageCountPerHourRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@@ -32,15 +32,15 @@ class UserRepositoryABC(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_users_with_activity_by_server_id(self, server_id: int) -> List[User]:
|
def get_user_by_discord_id_and_server_id(
|
||||||
|
self, discord_id: int, server_id: int
|
||||||
|
) -> User:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
|
def find_user_by_discord_id_and_server_id(
|
||||||
pass
|
self, discord_id: int, server_id: int
|
||||||
|
) -> Optional[User]:
|
||||||
@abstractmethod
|
|
||||||
def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]:
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user