Compare commits
	
		
			127 Commits
		
	
	
		
			1.2.1
			...
			bc528f1474
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bc528f1474 | |||
| d67ba924dc | |||
| e054c04c96 | |||
| c846614274 | |||
| 83764b3cee | |||
| 4553490266 | |||
| 35aa2574f8 | |||
| ccae285b81 | |||
| 887a02a7af | |||
| f484c553b3 | |||
| c5eca69db1 | |||
| d1a04c537c | |||
| 72715aac62 | |||
| e516def7ef | |||
| f1f5954dfc | |||
| 266dacb301 | |||
| 280cd9827d | |||
| 36998470e8 | |||
| 53c6bf4208 | |||
| 4e80e3ccb7 | |||
| ba173a6743 | |||
| 84ff2a8a9b | |||
| 13bc38fea8 | |||
| dfdf0555d7 | |||
| 39299eb11b | |||
| dfb6751bf9 | |||
| 4a75635a55 | |||
| f6b2739394 | |||
| 36d2605655 | |||
| af891fa588 | |||
| af348b85a4 | |||
| 7ed621a25b | |||
| 013f953a7f | |||
| 4163532696 | |||
| b6a1172cc1 | |||
| 20bdb6bd98 | |||
| 3f13f65932 | |||
| 711e184895 | |||
| 7e3975f4be | |||
| d4f4f39522 | |||
| af9c55e4b1 | |||
| e3172d6f24 | |||
| 0706579f62 | |||
| ad3fc94923 | |||
| 69882af0bd | |||
| 560c7650bd | |||
| b0fb12f841 | |||
| 18386339b7 | |||
| 4d980331e2 | |||
| e6667c78c8 | |||
| 9976c59302 | |||
| 293c8cd81c | |||
| 8f4ea56184 | |||
| 898e005978 | |||
| db3e6183ba | |||
| 0a47393510 | |||
| 6c5b514b41 | |||
| 84f994fd58 | |||
| 3d21123786 | |||
| 36887f1bdf | |||
| 0e4419312b | |||
| 94732b7227 | |||
| 4233e089f8 | |||
| db61a764eb | |||
| 919eef79f6 | |||
| 0aa690b984 | |||
| b6b9bfabf5 | |||
| d927ab8fb7 | |||
| a2dd447dbd | |||
| 8a76b46165 | |||
| af3084ad36 | |||
| 285b8bdbe4 | |||
| e2da4f09ee | |||
| 4ed99da689 | |||
| bc94d31a8d | |||
| 0d3db75190 | |||
| 090f217f93 | |||
| b98828fce3 | |||
| 5f8ae787f0 | |||
| 0c807a7de7 | |||
| 2dc60acaa6 | |||
| 29ea96a5e5 | |||
| 026331b397 | |||
| bfe74ad1c5 | |||
| 7c8c2bef70 | |||
| 4ccb57e6a3 | |||
| c8d3bf780d | |||
| 8788b727c5 | |||
| 5e9280d972 | |||
| bd856d0143 | |||
| da57063b68 | |||
| 171aa63df9 | |||
| 74dba4b981 | |||
| a3ebd07093 | |||
| 2de5afd648 | |||
| e8cc42e155 | |||
| 20e20969e4 | |||
| 802d5478d1 | |||
| 05f718f3ae | |||
| 7682b966a8 | |||
| 7cb4f03554 | |||
| b1b74b2551 | |||
| bbad4100dc | |||
| 25df0e4876 | |||
| 4ba40b826a | |||
| 06a0eba5c5 | |||
| fe5b0207c0 | |||
| e01c738cf0 | |||
| d2d59bdad7 | |||
| dd3bfa68c6 | |||
| 4e12ba5ffe | |||
| 35a8b8f592 | |||
| 5c8feed8aa | |||
| e018fdcbdf | |||
| 39b9def76c | |||
| 2801c617f6 | |||
| 5461a6d8dc | |||
| d93c3ad6c7 | |||
| aec7dac4c7 | |||
| 407ec08463 | |||
| 4628f31993 | |||
| 1f2fbc362f | |||
| 666b20d3a9 | |||
| 5de6710261 | |||
| e99e272029 | |||
| 650f612a6b | |||
| 38093ab817 | 
| @@ -6,9 +6,17 @@ on: | |||||||
|       - dev |       - dev | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   on-push-deploy_sh-edraft: |   pre-build: | ||||||
|     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|     container: sh-edraft.de/act-runner:latest |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Shutdown stack | ||||||
|  |         run: docker stack rm sdb_dev | ||||||
|  |  | ||||||
|  |   build-bot: | ||||||
|  |     needs: pre-build | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Setup docker |       - name: Setup docker | ||||||
|         uses: https://github.com/papodaca/install-docker-action@main |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
| @@ -22,10 +30,44 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Prepare bot build |       - name: Prepare bot build | ||||||
|         run: | |         run: | | ||||||
|           cd bot |  | ||||||
|           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli |           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|  |           cd bot | ||||||
|           cpl i |           cpl i | ||||||
|  |  | ||||||
|  |       - name: Build docker bot | ||||||
|  |         run: | | ||||||
|  |           cd bot | ||||||
|  |           docker image prune -f | ||||||
|  |           cpl build | ||||||
|  |           docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-dev . | ||||||
|  |  | ||||||
|  |       - name: Login to registry git.sh-edraft.de | ||||||
|  |         uses: https://github.com/docker/login-action@v1 | ||||||
|  |         with: | ||||||
|  |           registry: git.sh-edraft.de | ||||||
|  |           username: ${{ secrets.CI_USERNAME }} | ||||||
|  |           password: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |  | ||||||
|  |       - name: Push image | ||||||
|  |         run: | | ||||||
|  |           cd bot | ||||||
|  |           docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-dev | ||||||
|  |  | ||||||
|  |   build-web: | ||||||
|  |     needs: pre-build | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Setup docker | ||||||
|  |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
|  |       - run: docker -v | ||||||
|  |  | ||||||
|  |       - name: Clone Repository | ||||||
|  |         uses: https://github.com/actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |           submodules: true | ||||||
|  |  | ||||||
|       - name: Setup node |       - name: Setup node | ||||||
|         uses: https://github.com/actions/setup-node@v3 |         uses: https://github.com/actions/setup-node@v3 | ||||||
|  |  | ||||||
| @@ -35,29 +77,45 @@ jobs: | |||||||
|           npm install -g ts-node |           npm install -g ts-node | ||||||
|           npm ci |           npm ci | ||||||
|  |  | ||||||
|       - name: Shutdown stack |  | ||||||
|         run: docker stack rm sdb_dev |  | ||||||
|  |  | ||||||
|       - name: Build docker bot |  | ||||||
|         run: | |  | ||||||
|           cd bot |  | ||||||
|           docker image prune -f |  | ||||||
|           cpl build |  | ||||||
|           docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-dev . |  | ||||||
|  |  | ||||||
|       - name: Build docker web |       - name: Build docker web | ||||||
|         run: | |         run: | | ||||||
|           cd web |           cd web | ||||||
|           docker image prune -f |           docker image prune -f | ||||||
|           cp src/favicon.dev.ico src/favicon.ico |           cp src/favicon.dev.ico src/favicon.ico | ||||||
|           npm run build |           npm run build | ||||||
|           docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-dev . |           docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-dev . | ||||||
|  |  | ||||||
|  |       - name: Login to registry git.sh-edraft.de | ||||||
|  |         uses: https://github.com/docker/login-action@v1 | ||||||
|  |         with: | ||||||
|  |           registry: git.sh-edraft.de | ||||||
|  |           username: ${{ secrets.CI_USERNAME }} | ||||||
|  |           password: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |  | ||||||
|  |       - name: Push image | ||||||
|  |         run: | | ||||||
|  |           cd web | ||||||
|  |           docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-dev | ||||||
|  |  | ||||||
|  |   deploy: | ||||||
|  |     needs: [ build-bot, build-web ] | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Clone Repository | ||||||
|  |         uses: https://github.com/actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |           submodules: true | ||||||
|  |  | ||||||
|  |       - name: Install cpl | ||||||
|  |         run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|  |  | ||||||
|       - name: Set version |       - name: Set version | ||||||
|         run: | |         run: | | ||||||
|           cd bot/docker |           cd bot/docker | ||||||
|           chmod +x ./set-docker-compose-image-version.sh |           chmod +x ./set-docker-compose-image-version.sh | ||||||
|           ./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-dev sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-dev |           ./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-dev git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-dev | ||||||
|  |  | ||||||
|       - name: Deploy Stack to sh-edraft.de |       - name: Deploy Stack to sh-edraft.de | ||||||
|         uses: https://github.com/kgierke/portainer-stack-deployment@v1 |         uses: https://github.com/kgierke/portainer-stack-deployment@v1 | ||||||
|   | |||||||
| @@ -6,9 +6,17 @@ on: | |||||||
|       - master |       - master | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   on-push-deploy_sh-edraft: |   pre-build: | ||||||
|     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|     container: sh-edraft.de/act-runner:latest |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Shutdown stack | ||||||
|  |         run: docker stack rm sdb_prod | ||||||
|  |  | ||||||
|  |   build-bot: | ||||||
|  |     needs: pre-build | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Setup docker |       - name: Setup docker | ||||||
|         uses: https://github.com/papodaca/install-docker-action@main |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
| @@ -22,10 +30,44 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Prepare bot build |       - name: Prepare bot build | ||||||
|         run: | |         run: | | ||||||
|           cd bot |  | ||||||
|           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli |           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|  |           cd bot | ||||||
|           cpl i |           cpl i | ||||||
|  |  | ||||||
|  |       - name: Build docker bot | ||||||
|  |         run: | | ||||||
|  |           cd bot | ||||||
|  |           docker image prune -f | ||||||
|  |           cpl build | ||||||
|  |           docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv) . | ||||||
|  |  | ||||||
|  |       - name: Login to registry git.sh-edraft.de | ||||||
|  |         uses: https://github.com/docker/login-action@v1 | ||||||
|  |         with: | ||||||
|  |           registry: git.sh-edraft.de | ||||||
|  |           username: ${{ secrets.CI_USERNAME }} | ||||||
|  |           password: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |  | ||||||
|  |       - name: Push image | ||||||
|  |         run: | | ||||||
|  |           cd bot | ||||||
|  |           docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv) | ||||||
|  |  | ||||||
|  |   build-web: | ||||||
|  |     needs: pre-build | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Setup docker | ||||||
|  |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
|  |       - run: docker -v | ||||||
|  |  | ||||||
|  |       - name: Clone Repository | ||||||
|  |         uses: https://github.com/actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |           submodules: true | ||||||
|  |  | ||||||
|       - name: Setup node |       - name: Setup node | ||||||
|         uses: https://github.com/actions/setup-node@v3 |         uses: https://github.com/actions/setup-node@v3 | ||||||
|  |  | ||||||
| @@ -35,28 +77,44 @@ jobs: | |||||||
|           npm install -g ts-node |           npm install -g ts-node | ||||||
|           npm ci |           npm ci | ||||||
|  |  | ||||||
|       - name: Shutdown stack |  | ||||||
|         run: docker stack rm sdb_prod |  | ||||||
|  |  | ||||||
|       - name: Build docker bot |  | ||||||
|         run: | |  | ||||||
|           cd bot |  | ||||||
|           docker image prune -f |  | ||||||
|           cpl build |  | ||||||
|           docker build -t sh-edraft.de/sdb-bot:$(cpl gv) . |  | ||||||
|  |  | ||||||
|       - name: Build docker web |       - name: Build docker web | ||||||
|         run: | |         run: | | ||||||
|           cd web |           cd web | ||||||
|           docker image prune -f |           docker image prune -f | ||||||
|           npm run build |           npm run build | ||||||
|           docker build -t sh-edraft.de/sdb-web:$(npm run -s gv) . |           docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv) . | ||||||
|  |  | ||||||
|  |       - name: Login to registry git.sh-edraft.de | ||||||
|  |         uses: https://github.com/docker/login-action@v1 | ||||||
|  |         with: | ||||||
|  |           registry: git.sh-edraft.de | ||||||
|  |           username: ${{ secrets.CI_USERNAME }} | ||||||
|  |           password: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |  | ||||||
|  |       - name: Push image | ||||||
|  |         run: | | ||||||
|  |           cd web | ||||||
|  |           docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv) | ||||||
|  |  | ||||||
|  |   deploy: | ||||||
|  |     needs: [ build-bot, build-web ] | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Clone Repository | ||||||
|  |         uses: https://github.com/actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |           submodules: true | ||||||
|  |  | ||||||
|  |       - name: Install cpl | ||||||
|  |         run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|  |  | ||||||
|       - name: Set version |       - name: Set version | ||||||
|         run: | |         run: | | ||||||
|           cd bot/docker |           cd bot/docker | ||||||
|           chmod +x ./set-docker-compose-image-version.sh |           chmod +x ./set-docker-compose-image-version.sh | ||||||
|           ./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv) sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;) |           ./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv) git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;) | ||||||
|  |  | ||||||
|       - name: Deploy Stack to sh-edraft.de |       - name: Deploy Stack to sh-edraft.de | ||||||
|         uses: https://github.com/kgierke/portainer-stack-deployment@v1 |         uses: https://github.com/kgierke/portainer-stack-deployment@v1 | ||||||
|   | |||||||
| @@ -6,9 +6,17 @@ on: | |||||||
|       - staging |       - staging | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   on-push-deploy_sh-edraft: |   pre-build: | ||||||
|     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|     container: sh-edraft.de/act-runner:latest |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Shutdown stack | ||||||
|  |         run: docker stack rm sdb_staging | ||||||
|  |  | ||||||
|  |   build-bot: | ||||||
|  |     needs: pre-build | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Setup docker |       - name: Setup docker | ||||||
|         uses: https://github.com/papodaca/install-docker-action@main |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
| @@ -22,10 +30,44 @@ jobs: | |||||||
|  |  | ||||||
|       - name: Prepare bot build |       - name: Prepare bot build | ||||||
|         run: | |         run: | | ||||||
|           cd bot |  | ||||||
|           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli |           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|  |           cd bot | ||||||
|           cpl i |           cpl i | ||||||
|  |  | ||||||
|  |       - name: Build docker bot | ||||||
|  |         run: | | ||||||
|  |           cd bot | ||||||
|  |           docker image prune -f | ||||||
|  |           cpl build | ||||||
|  |           docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-staging . | ||||||
|  |  | ||||||
|  |       - name: Login to registry git.sh-edraft.de | ||||||
|  |         uses: https://github.com/docker/login-action@v1 | ||||||
|  |         with: | ||||||
|  |           registry: git.sh-edraft.de | ||||||
|  |           username: ${{ secrets.CI_USERNAME }} | ||||||
|  |           password: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |  | ||||||
|  |       - name: Push image | ||||||
|  |         run: | | ||||||
|  |           cd bot | ||||||
|  |           docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-staging | ||||||
|  |  | ||||||
|  |   build-web: | ||||||
|  |     needs: pre-build | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Setup docker | ||||||
|  |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
|  |       - run: docker -v | ||||||
|  |  | ||||||
|  |       - name: Clone Repository | ||||||
|  |         uses: https://github.com/actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |           submodules: true | ||||||
|  |  | ||||||
|       - name: Setup node |       - name: Setup node | ||||||
|         uses: https://github.com/actions/setup-node@v3 |         uses: https://github.com/actions/setup-node@v3 | ||||||
|  |  | ||||||
| @@ -35,29 +77,45 @@ jobs: | |||||||
|           npm install -g ts-node |           npm install -g ts-node | ||||||
|           npm ci |           npm ci | ||||||
|  |  | ||||||
|       - name: Shutdown stack |  | ||||||
|         run: docker stack rm sdb_staging |  | ||||||
|  |  | ||||||
|       - name: Build docker bot |  | ||||||
|         run: | |  | ||||||
|           cd bot |  | ||||||
|           docker image prune -f |  | ||||||
|           cpl build |  | ||||||
|           docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-staging . |  | ||||||
|  |  | ||||||
|       - name: Build docker web |       - name: Build docker web | ||||||
|         run: | |         run: | | ||||||
|           cd web |           cd web | ||||||
|           docker image prune -f |           docker image prune -f | ||||||
|           cp src/favicon.staging.ico src/favicon.ico |           cp src/favicon.staging.ico src/favicon.ico | ||||||
|           npm run build |           npm run build | ||||||
|           docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-staging . |           docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-staging . | ||||||
|  |  | ||||||
|  |       - name: Login to registry git.sh-edraft.de | ||||||
|  |         uses: https://github.com/docker/login-action@v1 | ||||||
|  |         with: | ||||||
|  |           registry: git.sh-edraft.de | ||||||
|  |           username: ${{ secrets.CI_USERNAME }} | ||||||
|  |           password: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |  | ||||||
|  |       - name: Push image | ||||||
|  |         run: | | ||||||
|  |           cd web | ||||||
|  |           docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-staging | ||||||
|  |  | ||||||
|  |   deploy: | ||||||
|  |     needs: [ build-bot, build-web ] | ||||||
|  |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|  |     container: git.sh-edraft.de/sh-edraft.de/act-runner:latest | ||||||
|  |     steps: | ||||||
|  |       - name: Clone Repository | ||||||
|  |         uses: https://github.com/actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.CI_ACCESS_TOKEN }} | ||||||
|  |           submodules: true | ||||||
|  |  | ||||||
|  |       - name: Install cpl | ||||||
|  |         run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|  |  | ||||||
|       - name: Set version |       - name: Set version | ||||||
|         run: | |         run: | | ||||||
|           cd bot/docker |           cd bot/docker | ||||||
|           chmod +x ./set-docker-compose-image-version.sh |           chmod +x ./set-docker-compose-image-version.sh | ||||||
|           ./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-staging sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-staging |           ./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-staging git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-staging | ||||||
|  |  | ||||||
|       - name: Deploy Stack to sh-edraft.de |       - name: Deploy Stack to sh-edraft.de | ||||||
|         uses: https://github.com/kgierke/portainer-stack-deployment@v1 |         uses: https://github.com/kgierke/portainer-stack-deployment@v1 | ||||||
|   | |||||||
| @@ -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 ./", | ||||||
|   | |||||||
 Submodule bot/docker updated: 9c0dc59534...36ed43055d
									
								
							| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								bot/src/bot/bot
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								bot/src/bot/bot
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -4,7 +4,7 @@ | |||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "2", |       "Minor": "2", | ||||||
|       "Micro": "1" |       "Micro": "5" | ||||||
|     }, |     }, | ||||||
|     "Author": "Sven Heidemann", |     "Author": "Sven Heidemann", | ||||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", |     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||||
| @@ -16,7 +16,6 @@ | |||||||
|     "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", | ||||||
| @@ -33,11 +32,14 @@ | |||||||
|       "cryptography==41.0.4", |       "cryptography==41.0.4", | ||||||
|       "discord==2.3.2", |       "discord==2.3.2", | ||||||
|       "bs4==0.0.1", |       "bs4==0.0.1", | ||||||
|       "lxml==4.9.3" |       "lxml==4.9.3", | ||||||
|  |       "python-valve==0.2.1", | ||||||
|  |       "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": {}, | ||||||
| @@ -69,7 +71,6 @@ | |||||||
|       "../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 updated: c11ca6f2e8...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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								bot/src/bot/extension/clean_logs_extension.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								bot/src/bot/extension/clean_logs_extension.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | 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}")) | ||||||
|  |         ) | ||||||
| @@ -6,6 +6,7 @@ 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 | ||||||
| @@ -31,6 +32,7 @@ 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,7 +12,6 @@ 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 | ||||||
| @@ -30,7 +29,6 @@ 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,6 +15,7 @@ from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | |||||||
| from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.logging.command_logger import CommandLogger | from bot_core.logging.command_logger import CommandLogger | ||||||
| from bot_core.logging.database_logger import DatabaseLogger | from bot_core.logging.database_logger import DatabaseLogger | ||||||
|  | from bot_core.logging.event_logger import EventLogger | ||||||
| from bot_core.logging.message_logger import MessageLogger | from bot_core.logging.message_logger import MessageLogger | ||||||
| from bot_core.logging.task_logger import TaskLogger | from bot_core.logging.task_logger import TaskLogger | ||||||
| from bot_data.db_context import DBContext | from bot_data.db_context import DBContext | ||||||
| @@ -45,6 +46,7 @@ class Startup(StartupABC): | |||||||
|             services.add_singleton(CustomFileLoggerABC, DatabaseLogger) |             services.add_singleton(CustomFileLoggerABC, DatabaseLogger) | ||||||
|             services.add_singleton(CustomFileLoggerABC, MessageLogger) |             services.add_singleton(CustomFileLoggerABC, MessageLogger) | ||||||
|             services.add_singleton(CustomFileLoggerABC, TaskLogger) |             services.add_singleton(CustomFileLoggerABC, TaskLogger) | ||||||
|  |             services.add_singleton(CustomFileLoggerABC, EventLogger) | ||||||
|  |  | ||||||
|         if self._feature_flags.get_flag(FeatureFlagsEnum.api_module): |         if self._feature_flags.get_flag(FeatureFlagsEnum.api_module): | ||||||
|             services.add_singleton(CustomFileLoggerABC, ApiLogger) |             services.add_singleton(CustomFileLoggerABC, ApiLogger) | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "2", |       "Minor": "2", | ||||||
|       "Micro": "1" |       "Micro": "5" | ||||||
|     }, |     }, | ||||||
|     "Author": "", |     "Author": "", | ||||||
|     "AuthorEmail": "", |     "AuthorEmail": "", | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -14,7 +14,10 @@ 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: | ||||||
| @@ -30,6 +33,7 @@ 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 | ||||||
| @@ -39,6 +43,7 @@ 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) | ||||||
| @@ -70,17 +75,32 @@ 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( | ||||||
|  |             self._technician_config.feature_flags, FeatureFlagsEnum.basic_registration | ||||||
|  |         ): | ||||||
|  |             return | ||||||
|  |  | ||||||
|         dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) |         dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) | ||||||
|         self._auth_service.add_auth_user(dto) |         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( | ||||||
|  |             self._technician_config.feature_flags, FeatureFlagsEnum.basic_login | ||||||
|  |         ): | ||||||
|  |             return jsonify({}) | ||||||
|  |  | ||||||
|         dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) |         dto: AuthUserDTO = JSONProcessor.process(AuthUserDTO, request.get_json(force=True, silent=True)) | ||||||
|         result = await self._auth_service.login_async(dto) |         result = await self._auth_service.login_async(dto) | ||||||
|         return jsonify(result.to_dict()) |         return jsonify(result.to_dict()) | ||||||
| @@ -100,6 +120,11 @@ 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 | ||||||
|  |  | ||||||
| @@ -110,6 +135,11 @@ 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( | ||||||
|  |             self._technician_config.feature_flags, FeatureFlagsEnum.basic_login | ||||||
|  |         ): | ||||||
|  |             return "", 409 | ||||||
|  |  | ||||||
|         dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True)) |         dto: ResetPasswordDTO = JSONProcessor.process(ResetPasswordDTO, request.get_json(force=True, silent=True)) | ||||||
|         await self._auth_service.reset_password_async(dto) |         await self._auth_service.reset_password_async(dto) | ||||||
|         return "", 200 |         return "", 200 | ||||||
|   | |||||||
| @@ -12,6 +12,9 @@ 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: | ||||||
| @@ -82,3 +85,11 @@ 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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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 modules.permission.abc.permission_service_abc import PermissionServiceABC | from bot_core.abc.permission_service_abc import PermissionServiceABC | ||||||
|  |  | ||||||
|  |  | ||||||
| class AuthUserTransformer(TransformerABC): | class AuthUserTransformer(TransformerABC): | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -48,6 +48,16 @@ class ClientUtilsABC(ABC): | |||||||
|     def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List: |     def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List: | ||||||
|         pass |         pass | ||||||
|  |  | ||||||
|  |     @abstractmethod | ||||||
|  |     def update_user_message_xp_count_by_hour( | ||||||
|  |         self, | ||||||
|  |         created_at: datetime, | ||||||
|  |         user: User, | ||||||
|  |         settings: ServerConfig, | ||||||
|  |         is_reaction: bool = False, | ||||||
|  |     ): | ||||||
|  |         pass | ||||||
|  |  | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( |     def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( | ||||||
|         self, |         self, | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ class TaskABC(commands.Cog): | |||||||
|  |  | ||||||
|     @ServiceProviderABC.inject |     @ServiceProviderABC.inject | ||||||
|     async def _wait_until_ready(self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC): |     async def _wait_until_ready(self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC): | ||||||
|         logger.debug(__name__, f"Waiting before {type(self).__name__}") |         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(): | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "2", |       "Minor": "2", | ||||||
|       "Micro": "1" |       "Micro": "5" | ||||||
|     }, |     }, | ||||||
|     "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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ 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 | ||||||
| @@ -27,3 +26,6 @@ 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,7 +16,6 @@ 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 | ||||||
| @@ -29,6 +28,9 @@ 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): | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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 modules.permission.abc.permission_service_abc import PermissionServiceABC | from bot_core.abc.permission_service_abc import PermissionServiceABC | ||||||
|  |  | ||||||
|  |  | ||||||
| class CoreExtension(ApplicationExtensionABC): | class CoreExtension(ApplicationExtensionABC): | ||||||
|   | |||||||
| @@ -1,20 +1,18 @@ | |||||||
| import asyncio |  | ||||||
|  |  | ||||||
| from cpl_core.configuration import ConfigurationABC | from cpl_core.configuration import ConfigurationABC | ||||||
| from cpl_core.logging import LoggerABC |  | ||||||
| from cpl_discord.events import OnReadyABC | from cpl_discord.events import OnReadyABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| from cpl_translation import TranslatePipe | from cpl_translation import TranslatePipe | ||||||
|  |  | ||||||
| from bot_core.abc.client_utils_abc import ClientUtilsABC | from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||||
| from bot_core.environment_variables import MAINTENANCE | from bot_core.environment_variables import MAINTENANCE | ||||||
|  | from bot_core.logging.event_logger import EventLogger | ||||||
|  |  | ||||||
|  |  | ||||||
| class CoreExtensionOnReadyEvent(OnReadyABC): | class CoreExtensionOnReadyEvent(OnReadyABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|         config: ConfigurationABC, |         config: ConfigurationABC, | ||||||
|         logger: LoggerABC, |         logger: EventLogger, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         client_utils: ClientUtilsABC, |         client_utils: ClientUtilsABC, | ||||||
|         t: TranslatePipe, |         t: TranslatePipe, | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ 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 | ||||||
| @@ -14,6 +15,7 @@ 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): | ||||||
| @@ -28,6 +30,7 @@ class CoreModule(ModuleABC): | |||||||
|         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) | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -1,15 +1,15 @@ | |||||||
| from cpl_core.logging import LoggerABC |  | ||||||
| from cpl_discord.events import OnReadyABC | from cpl_discord.events import OnReadyABC | ||||||
| from cpl_discord.service import DiscordBotServiceABC | from cpl_discord.service import DiscordBotServiceABC | ||||||
| from cpl_translation import TranslatePipe | from cpl_translation import TranslatePipe | ||||||
|  |  | ||||||
| from bot_core.abc.client_utils_abc import ClientUtilsABC | from bot_core.abc.client_utils_abc import ClientUtilsABC | ||||||
|  | from bot_core.logging.event_logger import EventLogger | ||||||
|  |  | ||||||
|  |  | ||||||
| class CoreOnReadyEvent(OnReadyABC): | class CoreOnReadyEvent(OnReadyABC): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|         logger: LoggerABC, |         logger: EventLogger, | ||||||
|         bot: DiscordBotServiceABC, |         bot: DiscordBotServiceABC, | ||||||
|         client_utils: ClientUtilsABC, |         client_utils: ClientUtilsABC, | ||||||
|         t: TranslatePipe, |         t: TranslatePipe, | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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 modules.permission.abc.permission_service_abc import PermissionServiceABC | from bot_core.abc.permission_service_abc import PermissionServiceABC | ||||||
|  |  | ||||||
|  |  | ||||||
| class CommandChecks: | class CommandChecks: | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								bot/src/bot_core/logging/event_logger.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								bot/src/bot_core/logging/event_logger.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | from cpl_core.configuration import ConfigurationABC | ||||||
|  | from cpl_core.environment import ApplicationEnvironmentABC | ||||||
|  | from cpl_core.time import TimeFormatSettings | ||||||
|  |  | ||||||
|  | from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class EventLogger(CustomFileLoggerABC): | ||||||
|  |     def __init__( | ||||||
|  |         self, | ||||||
|  |         config: ConfigurationABC, | ||||||
|  |         time_format: TimeFormatSettings, | ||||||
|  |         env: ApplicationEnvironmentABC, | ||||||
|  |     ): | ||||||
|  |         CustomFileLoggerABC.__init__(self, "Event", config, time_format, env) | ||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -143,14 +143,13 @@ class ClientUtilsService(ClientUtilsABC): | |||||||
|  |  | ||||||
|         return _l.take(25) |         return _l.take(25) | ||||||
|  |  | ||||||
|     def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( |     def update_user_message_xp_count_by_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: | ||||||
| @@ -162,44 +161,50 @@ class ClientUtilsService(ClientUtilsABC): | |||||||
|                         user, |                         user, | ||||||
|                     ) |                     ) | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|                 self._db.save_changes() |                 self._db.save_changes() | ||||||
|  |  | ||||||
|                 umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.id, created_at) |                 umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.id, created_at) | ||||||
|         except Exception as e: |  | ||||||
|             self._logger.error( |  | ||||||
|                 __name__, |  | ||||||
|                 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 |  | ||||||
|  |  | ||||||
|  |             umcph.xp_count += settings.xp_per_reaction if is_reaction else 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 with id {umcph.id}", |                 f"Cannot update user message count per hour {created_at}", | ||||||
|                 e, |                 e, | ||||||
|             ) |             ) | ||||||
|             return False |             return False | ||||||
|  |  | ||||||
|         if umcph.xp_count is None: |     def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour( | ||||||
|  |         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 False | ||||||
|  |  | ||||||
|             return umcph.xp_count > settings.max_message_xp_per_hour |             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 | ||||||
|  |  | ||||||
|     def get_ontime_for_user(self, user: User) -> float: |     def get_ontime_for_user(self, user: User) -> float: | ||||||
|         return round( |         return round( | ||||||
|             self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.id) |             sum( | ||||||
|             .where(lambda x: x.leaved_on is not None and x.joined_on is not None) |                 [ | ||||||
|             .sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600), |                     (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) | ||||||
|  |                     if join.leaved_on is not None and join.joined_on is not None | ||||||
|  |                 ] | ||||||
|  |             ), | ||||||
|             2, |             2, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
| @@ -214,7 +219,7 @@ 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, guild.emojis).where(lambda x: x.name == rule.emoji_name).single() |             emoji = List(discord.Emoji, [x for x in guild.emojis if 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") | ||||||
|   | |||||||
| @@ -1,9 +1,8 @@ | |||||||
| 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 | ||||||
| @@ -66,74 +65,76 @@ class DataIntegrityService: | |||||||
|  |  | ||||||
|         self._is_for_shutdown = False |         self._is_for_shutdown = False | ||||||
|  |  | ||||||
|     def _check_known_users(self): |     async def check_data_integrity(self, is_for_shutdown=False): | ||||||
|         self._logger.debug(__name__, f"Start checking KnownUsers table, {len(self._bot.users)}") |         self._logger.info(__name__, f"Data integrity service started") | ||||||
|         for u in self._bot.users: |         if is_for_shutdown != self._is_for_shutdown: | ||||||
|             u: discord.User = u |             self._is_for_shutdown = is_for_shutdown | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|                 if u.bot: |  | ||||||
|                     self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot") |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|                 user = self._known_users.find_user_by_discord_id(u.id) |  | ||||||
|                 if user is not None: |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|                 self._logger.warn(__name__, f"Unknown user: {u.id}") |  | ||||||
|                 self._logger.debug(__name__, f"Add user: {u.id}") |  | ||||||
|                 self._known_users.add_user(KnownUser(u.id)) |  | ||||||
|                 self._db_context.save_changes() |  | ||||||
|  |  | ||||||
|                 user = self._known_users.find_user_by_discord_id(u.id) |  | ||||||
|                 if user is None: |  | ||||||
|                     self._logger.fatal(__name__, f"Cannot add user: {u.id}") |  | ||||||
|  |  | ||||||
|                 self._logger.debug(__name__, f"Added user: {u.id}") |  | ||||||
|             except Exception as e: |  | ||||||
|                 self._logger.error(__name__, f"Cannot get user", e) |  | ||||||
|  |  | ||||||
|     def _check_servers(self): |  | ||||||
|         self._logger.debug(__name__, f"Start checking Servers table") |  | ||||||
|             for g in self._bot.guilds: |             for g in self._bot.guilds: | ||||||
|             g: discord.Guild = g |                 self._logger.debug(__name__, f"Start check for server: {g.id}") | ||||||
|             try: |                 s = self._get_or_create_server(g) | ||||||
|                 server = self._servers.find_server_by_discord_id(g.id) |                 self._logger.debug(__name__, f"Start check for clients") | ||||||
|                 if server is not None: |                 self._check_clients(g.id, s) | ||||||
|  |  | ||||||
|  |                 for m in [m for m in g.members if not m.bot]: | ||||||
|  |                     await self._check_default_role(m) | ||||||
|  |                     self._check_known_user(m.id) | ||||||
|  |  | ||||||
|  |                     self._logger.debug(__name__, f"Start check for member: {g.id}@{m.id}") | ||||||
|  |                     u = self._get_or_create_user(s, m.id) | ||||||
|  |  | ||||||
|  |                     self._logger.debug(__name__, f"Start check for user joined server: {g.id}@{m.id}") | ||||||
|  |                     self._check_user_join(g, m, u) | ||||||
|  |  | ||||||
|  |                     self._logger.debug(__name__, f"Start check for user joined voice channels: {g.id}@{m.id}") | ||||||
|  |                     self._check_user_joined_vc(g.id, m, u) | ||||||
|  |  | ||||||
|  |                     self._logger.debug(__name__, f"Start check for user joined game servers: {g.id}@{m.id}") | ||||||
|  |                     self._check_user_joined_gs(g.id, m.id, u) | ||||||
|  |  | ||||||
|  |                     self._logger.debug(__name__, f"Start check for user got achievements: {g.id}@{m.id}") | ||||||
|  |                     await self._check_for_user_achievements(u) | ||||||
|  |  | ||||||
|  |                 for m in [m for m in g.members if m.bot]: | ||||||
|  |                     u = self._users.find_user_by_discord_id_and_server_id(m.id, s.id) | ||||||
|  |                     if u is None: | ||||||
|                         continue |                         continue | ||||||
|  |  | ||||||
|                 self._logger.warn(__name__, f"Server not found in database: {g.id}") |                     self._remove_bot(u) | ||||||
|                 self._logger.debug(__name__, f"Add server: {g.id}") |             self._logger.info(__name__, f"Data integrity service finished") | ||||||
|                 self._servers.add_server(Server(g.id)) |         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() |             self._db_context.save_changes() | ||||||
|  |  | ||||||
|                 server = self._servers.find_server_by_discord_id(g.id) |             server = self._servers.find_server_by_discord_id(guild.id) | ||||||
|             if server is None: |             if server is None: | ||||||
|                     self._logger.fatal(__name__, f"Cannot add server: {g.id}") |                 self._logger.fatal(__name__, f"Cannot add server: {guild.id}") | ||||||
|  |  | ||||||
|                 self._logger.debug(__name__, f"Added server: {g.id}") |             self._logger.trace(__name__, f"Added server: {guild.id}") | ||||||
|  |             return server | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot get server", e) |             self._logger.error(__name__, f"Cannot get server", e) | ||||||
|  |  | ||||||
|         results = self._servers.get_servers() |     def _check_clients(self, guild_id: int, server: Server): | ||||||
|         if results is None or len(results) == 0: |  | ||||||
|             self._logger.error(__name__, f"Table Servers is empty!") |  | ||||||
|  |  | ||||||
|     def _check_clients(self): |  | ||||||
|         self._logger.debug(__name__, f"Start checking Clients table") |  | ||||||
|         for g in self._bot.guilds: |  | ||||||
|             g: discord.Guild = g |  | ||||||
|         try: |         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}") |  | ||||||
|  |  | ||||||
|             client = self._clients.find_client_by_server_id(server.id) |             client = self._clients.find_client_by_server_id(server.id) | ||||||
|             if client is not None: |             if client is not None: | ||||||
|                     continue |                 return | ||||||
|  |  | ||||||
|             self._logger.warn( |             self._logger.warn( | ||||||
|                 __name__, |                 __name__, | ||||||
|                     f"Client for server {g.id} not found in database: {self._bot.user.id}", |                 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._logger.debug(__name__, f"Add client: {self._bot.user.id}") | ||||||
|             self._clients.add_client(Client(self._bot.user.id, 0, 0, 0, 0, 0, server)) |             self._clients.add_client(Client(self._bot.user.id, 0, 0, 0, 0, 0, server)) | ||||||
| @@ -143,10 +144,10 @@ class DataIntegrityService: | |||||||
|             if client is None: |             if client is None: | ||||||
|                 self._logger.fatal( |                 self._logger.fatal( | ||||||
|                     __name__, |                     __name__, | ||||||
|                         f"Cannot add client {self._bot.user.id} for server {g.id}", |                     f"Cannot add client {self._bot.user.id} for server {guild_id}", | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|                 self._logger.debug(__name__, f"Added client: {g.id}") |             self._logger.trace(__name__, f"Added client: {guild_id}") | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot get client", e) |             self._logger.error(__name__, f"Cannot get client", e) | ||||||
|  |  | ||||||
| @@ -154,32 +155,37 @@ class DataIntegrityService: | |||||||
|         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_users(self): |     def _check_known_user(self, member_id: int): | ||||||
|         self._logger.debug(__name__, f"Start checking Users table") |  | ||||||
|         for g in self._bot.guilds: |  | ||||||
|             g: discord.Guild = g |  | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|                 server = self._servers.find_server_by_discord_id(g.id) |             if self._known_users.find_user_by_discord_id(member_id) is not None: | ||||||
|                 if server is None: |                 return | ||||||
|                     self._logger.fatal(__name__, f"Server not found in database: {g.id}") |  | ||||||
|  |  | ||||||
|                 for u in g.members: |             self._logger.warn(__name__, f"Unknown user: {member_id}") | ||||||
|                     u: Union[discord.Member, discord.User] = u |             self._logger.trace(__name__, f"Add known user: {member_id}") | ||||||
|                     if u.bot: |             self._known_users.add_user(KnownUser(member_id)) | ||||||
|                         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, None, server)) |  | ||||||
|             self._db_context.save_changes() |             self._db_context.save_changes() | ||||||
|  |  | ||||||
|                     self._logger.debug(__name__, f"Added User: {u.id}") |             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: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot get User", e) |             self._logger.error(__name__, f"Cannot get User", e) | ||||||
|  |  | ||||||
| @@ -187,63 +193,34 @@ class DataIntegrityService: | |||||||
|         if results is None or len(results) == 0: |         if results is None or len(results) == 0: | ||||||
|             self._logger.error(__name__, f"Table Users is empty!") |             self._logger.error(__name__, f"Table Users is empty!") | ||||||
|  |  | ||||||
|     def _check_user_joins(self): |     def _check_user_join(self, guild: Guild, member: Member, user: User): | ||||||
|         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: |         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) |             join = self._user_joins.find_active_user_joined_server_by_user_id(user.id) | ||||||
|             if join is not None: |             if join is not None: | ||||||
|                         continue |                 return | ||||||
|  |  | ||||||
|                     m: discord.Member = u |  | ||||||
|             self._logger.warn( |             self._logger.warn( | ||||||
|                 __name__, |                 __name__, | ||||||
|                         f"Active UserJoinedServer not found in database: {guild.id}:{u.id}@{m.joined_at}", |                 f"Active UserJoinedServer not found in database: {guild.id}:{member.id}@{member.joined_at}", | ||||||
|             ) |             ) | ||||||
|             self._logger.debug( |             self._logger.debug( | ||||||
|                 __name__, |                 __name__, | ||||||
|                         f"Add UserJoinedServer: {guild.id}:{u.id}@{m.joined_at}", |                 f"Add UserJoinedServer: {guild.id}:{member.id}@{member.joined_at}", | ||||||
|                     ) |  | ||||||
|                     self._user_joins.add_user_joined_server( |  | ||||||
|                         UserJoinedServer(user, self._dtp.transform(m.joined_at), None) |  | ||||||
|             ) |             ) | ||||||
|  |             self._user_joins.add_user_joined_server(UserJoinedServer(user, self._dtp.transform(member.joined_at), None)) | ||||||
|             self._db_context.save_changes() |             self._db_context.save_changes() | ||||||
|  |  | ||||||
|                     self._logger.debug(__name__, f"Added UserJoinedServer: {u.id}") |             self._logger.trace(__name__, f"Added UserJoinedServer: {member.id}") | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot get UserJoinedServer", e) |             self._logger.error(__name__, f"Cannot get UserJoinedServer", e) | ||||||
|  |  | ||||||
|             results = self._users.get_users() |         try: | ||||||
|             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() |             joins = self._user_joins.get_user_joined_servers() | ||||||
|             for join in joins: |             for join in [x for x in joins if x.user.server.discord_id == guild.id and x.leaved_on is None]: | ||||||
|                 join: UserJoinedServer = join |  | ||||||
|                 if join.user.server.discord_id != guild.id: |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|                 if join.leaved_on is not None: |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|                 dc_user = guild.get_member(join.user.discord_id) |                 dc_user = guild.get_member(join.user.discord_id) | ||||||
|                 if dc_user is None: |                 if dc_user is not None: | ||||||
|  |                     continue | ||||||
|  |  | ||||||
|                 self._logger.warn( |                 self._logger.warn( | ||||||
|                     __name__, |                     __name__, | ||||||
|                     f"User {join.user.discord_id} already left the server.", |                     f"User {join.user.discord_id} already left the server.", | ||||||
| @@ -252,42 +229,26 @@ class DataIntegrityService: | |||||||
|                 self._user_joins.update_user_joined_server(join) |                 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_joins_vc(self): |     def _check_user_joined_vc(self, guild_id: int, member: Member, user: User): | ||||||
|         self._logger.debug(__name__, f"Start checking UserJoinedVoiceChannel table") |         settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}") | ||||||
|         for guild in self._bot.guilds: |  | ||||||
|             guild: discord.Guild = guild |  | ||||||
|             settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") |  | ||||||
|  |  | ||||||
|             server = self._servers.find_server_by_discord_id(guild.id) |  | ||||||
|             if server is None: |  | ||||||
|                 self._logger.fatal(__name__, f"Server not found in database: {guild.id}") |  | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             # close open voice states |             # 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 |  | ||||||
|  |  | ||||||
|                     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_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.id) |             joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.id) | ||||||
|             if joins is None or len(joins) == 0: |             if joins is None or len(joins) == 0: | ||||||
|                         continue |                 return | ||||||
|  |  | ||||||
|             for join in joins: |             for join in joins: | ||||||
|                 self._logger.warn( |                 self._logger.warn( | ||||||
|                     __name__, |                     __name__, | ||||||
|                             f"Active UserJoinedVoiceChannel found in database: {guild.id}:{member.id}@{join.joined_on}", |                     f"Active UserJoinedVoiceChannel found in database: {guild_id}:{member.id}@{join.joined_on}", | ||||||
|                 ) |                 ) | ||||||
|                 join.leaved_on = datetime.now() |                 join.leaved_on = datetime.now() | ||||||
|  |  | ||||||
|                         if ( |                 if ((join.leaved_on - join.joined_on).total_seconds() / 60 / 60) > settings.max_voice_state_hours: | ||||||
|                             (join.leaved_on - join.joined_on).total_seconds() / 60 / 60 |  | ||||||
|                         ) > settings.max_voice_state_hours: |  | ||||||
|                     join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours) |                     join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours) | ||||||
|  |  | ||||||
|                 self._user_joins_vc.update_user_joined_voice_channel(join) |                 self._user_joins_vc.update_user_joined_voice_channel(join) | ||||||
| @@ -301,59 +262,30 @@ class DataIntegrityService: | |||||||
|                     return |                     return | ||||||
|  |  | ||||||
|             # add open voice states |             # 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: |             if member.voice is None or member.voice.channel.id in settings.afk_channel_ids: | ||||||
|                         continue |                 return | ||||||
|  |  | ||||||
|                     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()) |             join = UserJoinedVoiceChannel(user, member.voice.channel.id, datetime.now()) | ||||||
|             self._user_joins_vc.add_user_joined_voice_channel(join) |             self._user_joins_vc.add_user_joined_voice_channel(join) | ||||||
|             self._db_context.save_changes() |             self._db_context.save_changes() | ||||||
|  |  | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e) |             self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e) | ||||||
|  |  | ||||||
|     def _check_user_joined_gs(self): |     def _check_user_joined_gs(self, guild_id: int, member_id: int, user: User): | ||||||
|         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: |         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) |             joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.id) | ||||||
|             if joins is None or len(joins) == 0: |             if joins is None or len(joins) == 0: | ||||||
|                         continue |                 return | ||||||
|  |  | ||||||
|             for join in joins: |             for join in joins: | ||||||
|                 self._logger.warn( |                 self._logger.warn( | ||||||
|                     __name__, |                     __name__, | ||||||
|                             f"Active UserJoinedGameServer found in database: {guild.id}:{member.id}@{join.joined_on}", |                     f"Active UserJoinedGameServer found in database: {guild_id}:{member_id}@{join.joined_on}", | ||||||
|                 ) |                 ) | ||||||
|                 join.leaved_on = datetime.now() |                 join.leaved_on = datetime.now() | ||||||
|                         settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") |                 settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}") | ||||||
|  |  | ||||||
|                         if ( |                 if join.time > settings.max_voice_state_hours: | ||||||
|                             (join.leaved_on - join.joined_on).total_seconds() / 60 / 60 |  | ||||||
|                         ) > settings.max_voice_state_hours: |  | ||||||
|                     join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours) |                     join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours) | ||||||
|  |  | ||||||
|                 self._user_joined_gs.update_user_joined_game_server(join) |                 self._user_joined_gs.update_user_joined_game_server(join) | ||||||
| @@ -365,38 +297,19 @@ class DataIntegrityService: | |||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             self._logger.error(__name__, f"Cannot get UserJoinedGameServer", e) |             self._logger.error(__name__, f"Cannot get UserJoinedGameServer", e) | ||||||
|  |  | ||||||
|     async def _check_for_user_achievements(self): |     async def _check_for_user_achievements(self, user: User): | ||||||
|         self._logger.debug(__name__, f"Start checking UserGotAchievement table") |         try: | ||||||
|  |  | ||||||
|         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) |             await self._achievements.validate_achievements_for_user(user) | ||||||
|  |         except Exception as e: | ||||||
|  |             self._logger.error(__name__, f"Cannot check UserGotAchievement for {user.id}", e) | ||||||
|  |  | ||||||
|     async def _check_default_role(self): |     async def _check_default_role(self, member: Member): | ||||||
|         for guild in self._bot.guilds: |  | ||||||
|             for member in guild.members: |  | ||||||
|         await self._client_utils.check_default_role(member) |         await self._client_utils.check_default_role(member) | ||||||
|  |  | ||||||
|     def _check_for_bots(self): |     def _remove_bot(self, user: User): | ||||||
|         for guild in self._bot.guilds: |         known_user = self._known_users.find_user_by_discord_id(user.discord_id) | ||||||
|             server = self._servers.get_server_by_discord_id(guild.id) |         if known_user is not None: | ||||||
|  |             self._known_users.delete_user(known_user) | ||||||
|             for member in guild.members.where(lambda x: x.bot): |  | ||||||
|                 user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id) |  | ||||||
|                 if user is None: |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|         for join in self._user_joins.get_user_joined_servers_by_user_id(user.id): |         for join in self._user_joins.get_user_joined_servers_by_user_id(user.id): | ||||||
|             self._user_joins.delete_user_joined_server(join) |             self._user_joins.delete_user_joined_server(join) | ||||||
| @@ -404,18 +317,3 @@ class DataIntegrityService: | |||||||
|         self._user_joins_vc.delete_user_joined_voice_channel_by_user_id(user.id) |         self._user_joins_vc.delete_user_joined_voice_channel_by_user_id(user.id) | ||||||
|         self._users.delete_user(user) |         self._users.delete_user(user) | ||||||
|         self._db_context.save_changes() |         self._db_context.save_changes() | ||||||
|  |  | ||||||
|     async def check_data_integrity(self, is_for_shutdown=False): |  | ||||||
|         if is_for_shutdown != self._is_for_shutdown: |  | ||||||
|             self._is_for_shutdown = is_for_shutdown |  | ||||||
|  |  | ||||||
|         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() |  | ||||||
|         self._check_for_bots() |  | ||||||
|   | |||||||
							
								
								
									
										114
									
								
								bot/src/bot_core/service/permission_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								bot/src/bot_core/service/permission_service.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | |||||||
|  | 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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
| @@ -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.1" | __version__ = "1.2.5" | ||||||
|  |  | ||||||
| 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="1") | version_info = VersionInfo(major="1", minor="2", micro="5") | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								bot/src/bot_data/abc/scheduled_event_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								bot/src/bot_data/abc/scheduled_event_repository_abc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | 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 | ||||||
| @@ -19,10 +19,6 @@ class UserJoinedServerRepositoryABC(ABC): | |||||||
|     def get_user_joined_server_by_id(self, id: int) -> UserJoinedServer: |     def get_user_joined_server_by_id(self, id: int) -> UserJoinedServer: | ||||||
|         pass |         pass | ||||||
|  |  | ||||||
|     @abstractmethod |  | ||||||
|     def get_user_joined_server_by_server_id(self, server_id: int) -> UserJoinedServer: |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def get_user_joined_servers_by_user_id(self, user_id: int) -> list[UserJoinedServer]: |     def get_user_joined_servers_by_user_id(self, user_id: int) -> list[UserJoinedServer]: | ||||||
|         pass |         pass | ||||||
|   | |||||||
| @@ -31,6 +31,10 @@ class UserRepositoryABC(ABC): | |||||||
|     def get_users_by_server_id(self, server_id: int) -> List[User]: |     def get_users_by_server_id(self, server_id: int) -> List[User]: | ||||||
|         pass |         pass | ||||||
|  |  | ||||||
|  |     @abstractmethod | ||||||
|  |     def get_users_with_activity_by_server_id(self, server_id: int) -> List[User]: | ||||||
|  |         pass | ||||||
|  |  | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User: |     def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User: | ||||||
|         pass |         pass | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "2", |       "Minor": "2", | ||||||
|       "Micro": "1" |       "Micro": "5" | ||||||
|     }, |     }, | ||||||
|     "Author": "Sven Heidemann", |     "Author": "Sven Heidemann", | ||||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", |     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ from bot_data.abc.data_seeder_abc import DataSeederABC | |||||||
| from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC | from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC | ||||||
| from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC | from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC | ||||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC | from bot_data.abc.level_repository_abc import LevelRepositoryABC | ||||||
|  | from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC | ||||||
| from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||||
| from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC | from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC | ||||||
| @@ -45,6 +46,7 @@ from bot_data.service.client_repository_service import ClientRepositoryService | |||||||
| from bot_data.service.game_server_repository_service import GameServerRepositoryService | from bot_data.service.game_server_repository_service import GameServerRepositoryService | ||||||
| from bot_data.service.known_user_repository_service import KnownUserRepositoryService | from bot_data.service.known_user_repository_service import KnownUserRepositoryService | ||||||
| from bot_data.service.level_repository_service import LevelRepositoryService | from bot_data.service.level_repository_service import LevelRepositoryService | ||||||
|  | from bot_data.service.scheduled_event_repository_service import ScheduledEventRepositoryService | ||||||
| from bot_data.service.seeder_service import SeederService | from bot_data.service.seeder_service import SeederService | ||||||
| from bot_data.service.server_config_repository_service import ( | from bot_data.service.server_config_repository_service import ( | ||||||
|     ServerConfigRepositoryService, |     ServerConfigRepositoryService, | ||||||
| @@ -115,6 +117,7 @@ class DataModule(ModuleABC): | |||||||
|         services.add_transient(ServerConfigRepositoryABC, ServerConfigRepositoryService) |         services.add_transient(ServerConfigRepositoryABC, ServerConfigRepositoryService) | ||||||
|         services.add_transient(ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService) |         services.add_transient(ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService) | ||||||
|         services.add_transient(SteamSpecialOfferRepositoryABC, SteamSpecialOfferRepositoryService) |         services.add_transient(SteamSpecialOfferRepositoryABC, SteamSpecialOfferRepositoryService) | ||||||
|  |         services.add_transient(ScheduledEventRepositoryABC, ScheduledEventRepositoryService) | ||||||
|  |  | ||||||
|         services.add_transient(SeederService) |         services.add_transient(SeederService) | ||||||
|         services.add_transient(DataSeederABC, TechnicianConfigSeeder) |         services.add_transient(DataSeederABC, TechnicianConfigSeeder) | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ class DBContext(DatabaseContext): | |||||||
|             self._fails += 1 |             self._fails += 1 | ||||||
|             try: |             try: | ||||||
|                 time.sleep(0.5) |                 time.sleep(0.5) | ||||||
|  |                 self._logger.debug(__name__, "Retry select") | ||||||
|                 return self.select(statement) |                 return self.select(statement) | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 pass |                 pass | ||||||
|   | |||||||
| @@ -1,26 +0,0 @@ | |||||||
| # -*- coding: utf-8 -*- |  | ||||||
|  |  | ||||||
| """ |  | ||||||
| bot sh-edraft.de Discord bot |  | ||||||
| ~~~~~~~~~~~~~~~~~~~ |  | ||||||
|  |  | ||||||
| Discord bot for customers of sh-edraft.de |  | ||||||
|  |  | ||||||
| :copyright: (c) 2022 - 2023 sh-edraft.de |  | ||||||
| :license: MIT, see LICENSE for more details. |  | ||||||
|  |  | ||||||
| """ |  | ||||||
|  |  | ||||||
| __title__ = "bot_data.migration" |  | ||||||
| __author__ = "Sven Heidemann" |  | ||||||
| __license__ = "MIT" |  | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" |  | ||||||
| __version__ = "1.2.1" |  | ||||||
|  |  | ||||||
| from collections import namedtuple |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # imports |  | ||||||
|  |  | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") |  | ||||||
| version_info = VersionInfo(major="1", minor="2", micro="1") |  | ||||||
| @@ -1,127 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class AchievementsMigration(MigrationABC): |  | ||||||
|     name = "1.1.0_AchievementsMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `Achievements` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `Name` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Description` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Attribute` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Operator` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Value` VARCHAR(255) NOT NULL, |  | ||||||
|                         `ServerId` BIGINT, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`), |  | ||||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `AchievementsHistory` |  | ||||||
|                     ( |  | ||||||
|                         `Id`    BIGINT(20)  NOT NULL, |  | ||||||
|                         `Name` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Description` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Attribute` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Operator` VARCHAR(255) NOT NULL, |  | ||||||
|                         `Value` VARCHAR(255) NOT NULL, |  | ||||||
|                         `ServerId` BIGINT, |  | ||||||
|                         `Deleted`   BOOL DEFAULT FALSE, |  | ||||||
|                         `DateFrom`  DATETIME(6) NOT NULL, |  | ||||||
|                         `DateTo`    DATETIME(6) NOT NULL |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `UserGotAchievements` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `UserId` BIGINT, |  | ||||||
|                         `AchievementId` BIGINT, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`), |  | ||||||
|                         FOREIGN KEY (`UserId`) REFERENCES `Users`(`UserId`), |  | ||||||
|                         FOREIGN KEY (`AchievementId`) REFERENCES `Achievements`(`Id`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         # A join table history between users and achievements is not necessary. |  | ||||||
|  |  | ||||||
|         self._cursor.execute(str(f"""ALTER TABLE Users ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) |  | ||||||
|         self._cursor.execute(str(f"""ALTER TABLE Users ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) |  | ||||||
|         self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) |  | ||||||
|         self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""")) |  | ||||||
|  |  | ||||||
|         self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;""")) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TRIGGER `TR_AchievementsUpdate` |  | ||||||
|                         AFTER UPDATE |  | ||||||
|                         ON `Achievements` |  | ||||||
|                         FOR EACH ROW |  | ||||||
|                     BEGIN |  | ||||||
|                         INSERT INTO `AchievementsHistory` ( |  | ||||||
|                             `Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `DateFrom`, `DateTo` |  | ||||||
|                         ) |  | ||||||
|                         VALUES ( |  | ||||||
|                             OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|                         ); |  | ||||||
|                     END; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;""")) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TRIGGER `TR_AchievementsDelete` |  | ||||||
|                         AFTER DELETE |  | ||||||
|                         ON `Achievements` |  | ||||||
|                         FOR EACH ROW |  | ||||||
|                     BEGIN |  | ||||||
|                         INSERT INTO `AchievementsHistory` ( |  | ||||||
|                             `Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|                         ) |  | ||||||
|                         VALUES ( |  | ||||||
|                             OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|                         ); |  | ||||||
|                     END; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `Achievements`;") |  | ||||||
|  |  | ||||||
|         self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN MessageCount;""")) |  | ||||||
|         self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN ReactionCount;""")) |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ApiKeyMigration(MigrationABC): |  | ||||||
|     name = "1.0.0_ApiKeyMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `ApiKeys` ( |  | ||||||
|                 `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `Identifier` VARCHAR(255) NOT NULL, |  | ||||||
|                 `Key` VARCHAR(255) NOT NULL, |  | ||||||
|                 `CreatorId` BIGINT NULL, |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 PRIMARY KEY(`Id`), |  | ||||||
|                 FOREIGN KEY (`CreatorId`) REFERENCES `Users`(`UserId`), |  | ||||||
|                 CONSTRAINT UC_Identifier_Key UNIQUE (`Identifier`,`Key`), |  | ||||||
|                 CONSTRAINT UC_Key UNIQUE (`Key`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `ApiKeys`;") |  | ||||||
| @@ -1,61 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ApiMigration(MigrationABC): |  | ||||||
|     name = "0.3_ApiMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `AuthUsers` ( |  | ||||||
|                 `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `FirstName` VARCHAR(255), |  | ||||||
|                 `LastName` VARCHAR(255), |  | ||||||
|                 `EMail` VARCHAR(255), |  | ||||||
|                 `Password` VARCHAR(255), |  | ||||||
|                 `PasswordSalt` VARCHAR(255), |  | ||||||
|                 `RefreshToken` VARCHAR(255), |  | ||||||
|                 `ConfirmationId` VARCHAR(255) DEFAULT NULL, |  | ||||||
|                 `ForgotPasswordId` VARCHAR(255) DEFAULT NULL, |  | ||||||
|                 `OAuthId` VARCHAR(255) DEFAULT NULL, |  | ||||||
|                 `RefreshTokenExpiryTime` DATETIME(6) NOT NULL, |  | ||||||
|                 `AuthRole` INT NOT NULL DEFAULT 0, |  | ||||||
|                 `CreatedAt` DATETIME(6) NOT NULL, |  | ||||||
|                 `LastModifiedAt` DATETIME(6) NOT NULL, |  | ||||||
|                 PRIMARY KEY(`Id`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `AuthUserUsersRelations`( |  | ||||||
|                 `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `AuthUserId` BIGINT DEFAULT NULL, |  | ||||||
|                 `UserId` BIGINT DEFAULT NULL, |  | ||||||
|                 `CreatedAt` DATETIME(6) NOT NULL, |  | ||||||
|                 `LastModifiedAt` DATETIME(6) NOT NULL, |  | ||||||
|                 PRIMARY KEY(`Id`), |  | ||||||
|                 FOREIGN KEY (`AuthUserId`) REFERENCES `AuthUsers`(`Id`), |  | ||||||
|                 FOREIGN KEY (`UserId`) REFERENCES `Users`(`UserId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `AuthUsers`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `AuthUserUsersRelations`;") |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class AutoRoleFix1Migration(MigrationABC): |  | ||||||
|     name = "0.3.0_AutoRoleFixMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             ALTER TABLE AutoRoles ADD DiscordChannelId BIGINT NOT NULL AFTER ServerId; |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             ALTER TABLE AutoRoles DROP COLUMN DiscordChannelId; |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| @@ -1,53 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class AutoRoleMigration(MigrationABC): |  | ||||||
|     name = "0.2.1_AutoRoleMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `AutoRoles` ( |  | ||||||
|                 `AutoRoleId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `ServerId` BIGINT, |  | ||||||
|                 `DiscordMessageId` BIGINT NOT NULL, |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 PRIMARY KEY(`AutoRoleId`), |  | ||||||
|                 FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `AutoRoleRules` ( |  | ||||||
|                 `AutoRoleRuleId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `AutoRoleId` BIGINT, |  | ||||||
|                 `DiscordEmojiName` VARCHAR(64), |  | ||||||
|                 `DiscordRoleId` BIGINT NOT NULL, |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 PRIMARY KEY(`AutoRoleRuleId`), |  | ||||||
|                 FOREIGN KEY (`AutoRoleId`) REFERENCES `AutoRoles`(`AutoRoleId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `AutoRole`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `AutoRoleRules`;") |  | ||||||
| @@ -1,84 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class BirthdayMigration(MigrationABC): |  | ||||||
|     name = "1.2.0_BirthdayMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE Users |  | ||||||
|                     ADD Birthday DATE NULL AFTER MessageCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE UsersHistory |  | ||||||
|                     ADD Birthday DATE NULL AFTER MessageCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._exec(__file__, "users.sql") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Server |  | ||||||
|                     ADD XpForBirthday BIGINT(20) NOT NULL DEFAULT 0 AFTER XpPerAchievement; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_ServerHistory |  | ||||||
|                     ADD XpForBirthday BIGINT(20) NOT NULL DEFAULT 0 AFTER XpPerAchievement; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._exec(__file__, "config/server.sql") |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE Users DROP COLUMN Birthday; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE UsersHistory DROP COLUMN Birthday; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Server DROP COLUMN XpForBirthday; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_ServerHistory DROP COLUMN XpForBirthday; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| @@ -1,29 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ConfigFeatureFlagsMigration(MigrationABC): |  | ||||||
|     name = "1.1.0_ConfigFeatureFlagsMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str("""ALTER TABLE CFG_Technician ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;""") |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str("""ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;""") |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running downgrade") |  | ||||||
|         self._cursor.execute("ALTER TABLE CFG_Technician DROP COLUMN FeatureFlags;") |  | ||||||
|         self._cursor.execute("ALTER TABLE CFG_Server DROP COLUMN FeatureFlags;") |  | ||||||
| @@ -1,145 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ConfigMigration(MigrationABC): |  | ||||||
|     name = "1.1.0_ConfigMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|         self._server_upgrade() |  | ||||||
|         self._technician_upgrade() |  | ||||||
|  |  | ||||||
|         self._exec(__file__, "config/server.sql") |  | ||||||
|         self._exec(__file__, "config/server_afk_channels.sql") |  | ||||||
|         self._exec(__file__, "config/server_team_roles.sql") |  | ||||||
|         self._exec(__file__, "config/technician.sql") |  | ||||||
|         self._exec(__file__, "config/technician_ids.sql") |  | ||||||
|         self._exec(__file__, "config/technician_ping_urls.sql") |  | ||||||
|  |  | ||||||
|     def _server_upgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `CFG_Server` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `MessageDeleteTimer` BIGINT NOT NULL DEFAULT 6, |  | ||||||
|                         `NotificationChatId` BIGINT NOT NULL, |  | ||||||
|                         `MaxVoiceStateHours` BIGINT NOT NULL DEFAULT 6, |  | ||||||
|                         `XpPerMessage` BIGINT NOT NULL DEFAULT 1, |  | ||||||
|                         `XpPerReaction` BIGINT NOT NULL DEFAULT 1, |  | ||||||
|                         `MaxMessageXpPerHour` BIGINT NOT NULL DEFAULT 20, |  | ||||||
|                         `XpPerOntimeHour` BIGINT NOT NULL DEFAULT 10, |  | ||||||
|                         `XpPerEventParticipation` BIGINT NOT NULL DEFAULT 10, |  | ||||||
|                         `XpPerAchievement` BIGINT NOT NULL DEFAULT 10, |  | ||||||
|                         `AFKCommandChannelId` BIGINT NOT NULL, |  | ||||||
|                         `HelpVoiceChannelId` BIGINT NOT NULL, |  | ||||||
|                         `TeamChannelId` BIGINT NOT NULL, |  | ||||||
|                         `LoginMessageChannelId` BIGINT NOT NULL, |  | ||||||
|                         `ServerId` BIGINT NOT NULL, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`), |  | ||||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `CFG_ServerAFKChannelIds` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `ChannelId` BIGINT NOT NULL, |  | ||||||
|                         `ServerId` BIGINT NOT NULL, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`), |  | ||||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `CFG_ServerTeamRoleIds` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `RoleId` BIGINT NOT NULL, |  | ||||||
|                         `TeamMemberType` ENUM('Moderator', 'Admin') NOT NULL, |  | ||||||
|                         `ServerId` BIGINT NOT NULL, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`), |  | ||||||
|                         FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _technician_upgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `CFG_Technician` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `HelpCommandReferenceUrl` VARCHAR(255) NOT NULL, |  | ||||||
|                         `WaitForRestart` BIGINT NOT NULL DEFAULT 8, |  | ||||||
|                         `WaitForShutdown` BIGINT NOT NULL DEFAULT 8, |  | ||||||
|                         `CacheMaxMessages` BIGINT NOT NULL DEFAULT 1000000, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `CFG_TechnicianPingUrls` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `URL` VARCHAR(255) NOT NULL, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     CREATE TABLE IF NOT EXISTS `CFG_TechnicianIds` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `TechnicianId` BIGINT NOT NULL, |  | ||||||
|                         `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6), |  | ||||||
|                         `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), |  | ||||||
|                         PRIMARY KEY(`Id`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running downgrade") |  | ||||||
|         self._server_downgrade() |  | ||||||
|         self._technician_downgrade() |  | ||||||
|  |  | ||||||
|     def _server_downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `CFG_Server`;") |  | ||||||
|  |  | ||||||
|     def _technician_downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `CFG_Technician`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `CFG_TechnicianPingUrls`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `CFG_TechnicianIds`;") |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class DBHistoryMigration(MigrationABC): |  | ||||||
|     name = "1.0.0_DBHistoryMigration" |  | ||||||
|     prio = 1 |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._exec(__file__, "api_keys.sql") |  | ||||||
|         self._exec(__file__, "auth_users.sql") |  | ||||||
|         self._exec(__file__, "auth_user_users_relation.sql") |  | ||||||
|         self._exec(__file__, "auto_role_rules.sql") |  | ||||||
|         self._exec(__file__, "auto_roles.sql") |  | ||||||
|         self._exec(__file__, "clients.sql") |  | ||||||
|         self._exec(__file__, "game_servers.sql") |  | ||||||
|         self._exec(__file__, "known_users.sql") |  | ||||||
|         self._exec(__file__, "levels.sql") |  | ||||||
|         self._exec(__file__, "servers.sql") |  | ||||||
|         self._exec(__file__, "user_game_idents.sql") |  | ||||||
|         self._exec(__file__, "user_joined_game_servers.sql") |  | ||||||
|         self._exec(__file__, "user_joined_servers.sql") |  | ||||||
|         self._exec(__file__, "user_joined_voice_channel.sql") |  | ||||||
|         self._exec(__file__, "user_message_count_per_hour.sql") |  | ||||||
|         self._exec(__file__, "users.sql") |  | ||||||
|         self._exec(__file__, "user_warnings.sql") |  | ||||||
|  |  | ||||||
|         self._logger.debug(__name__, "Finished history upgrade") |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `ApiKeysHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `AuthUsersHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `AuthUserUsersRelationsHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `AutoRoleRulesHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `AutoRolesHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `ClientsHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `GameServersHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `KnownUsersHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `LevelsHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `ServersHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserGameIdentsHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserJoinedGameServerHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserJoinedServersHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserJoinedVoiceChannelHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserMessageCountPerHourHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UsersHistory`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserWarningsHistory`;") |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| ALTER TABLE `ApiKeys` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `ApiKeys` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `ApiKeysHistory` |  | ||||||
| ( |  | ||||||
|     `Id`         BIGINT(20)   NOT NULL, |  | ||||||
|     `Identifier` VARCHAR(255) NOT NULL, |  | ||||||
|     `Key`        VARCHAR(255) NOT NULL, |  | ||||||
|     `CreatorId`  BIGINT(20) DEFAULT NULL, |  | ||||||
|     `Deleted`    BOOL       DEFAULT FALSE, |  | ||||||
|     `DateFrom`   DATETIME(6)  NOT NULL, |  | ||||||
|     `DateTo`     DATETIME(6)  NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_ApiKeysUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_ApiKeysUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `ApiKeys` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `ApiKeysHistory` ( |  | ||||||
|         `Id`, `Identifier`, `Key`, `CreatorId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Identifier, OLD.Key, OLD.CreatorId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_ApiKeysDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_ApiKeysDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `ApiKeys` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `ApiKeysHistory` ( |  | ||||||
|         `Id`, `Identifier`, `Key`, `CreatorId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Identifier, OLD.Key, OLD.CreatorId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| ALTER TABLE `AuthUserUsersRelations` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `AuthUserUsersRelations` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `AuthUserUsersRelationsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`         BIGINT(20)  NOT NULL, |  | ||||||
|     `AuthUserId` BIGINT(20) DEFAULT NULL, |  | ||||||
|     `UserId`     BIGINT(20) DEFAULT NULL, |  | ||||||
|     `Deleted`    BOOL       DEFAULT FALSE, |  | ||||||
|     `DateFrom`   DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`     DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AuthUserUsersRelationsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AuthUserUsersRelationsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `AuthUserUsersRelations` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AuthUserUsersRelationsHistory` ( |  | ||||||
|         `Id`, `AuthUserId`, `UserId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.AuthUserId, OLD.UserId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AuthUserUsersRelationsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AuthUserUsersRelationsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `AuthUserUsersRelations` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AuthUserUsersRelationsHistory` ( |  | ||||||
|         `Id`, `AuthUserId`, `UserId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.AuthUserId, OLD.UserId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,62 +0,0 @@ | |||||||
| ALTER TABLE `AuthUsers` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `AuthUsers` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `AuthUsersHistory` |  | ||||||
| ( |  | ||||||
|     `Id`                     BIGINT(20)  NOT NULL, |  | ||||||
|     `FirstName`              VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `LastName`               VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `EMail`                  VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `Password`               VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `PasswordSalt`           VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `RefreshToken`           VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `ConfirmationId`         VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `ForgotPasswordId`       VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `OAuthId`                VARCHAR(255)         DEFAULT NULL, |  | ||||||
|     `RefreshTokenExpiryTime` DATETIME(6) NOT NULL, |  | ||||||
|     `AuthRole`               BIGINT(11)  NOT NULL DEFAULT 0, |  | ||||||
|     `Deleted`                BOOL                 DEFAULT FALSE, |  | ||||||
|     `DateFrom`               DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`                 DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AuthUsersUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AuthUsersUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `AuthUsers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AuthUsersHistory` ( |  | ||||||
|         `Id`, `FirstName`, `LastName`, `EMail`, `Password`, `PasswordSalt`, |  | ||||||
|         `RefreshToken`, `ConfirmationId`, `ForgotPasswordId`, `OAuthId`, |  | ||||||
|         `RefreshTokenExpiryTime`, `AuthRole`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.FirstName, OLD.LastName, OLD.EMail, OLD.Password, OLD.PasswordSalt, OLD.RefreshToken, |  | ||||||
|         OLD.ConfirmationId, OLD.ForgotPasswordId, OLD.OAuthId, OLD.RefreshTokenExpiryTime, OLD.AuthRole, |  | ||||||
|         OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AuthUsersDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AuthUsersDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `AuthUsers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AuthUsersHistory` ( |  | ||||||
|         `Id`, `FirstName`, `LastName`, `EMail`, `Password`, `PasswordSalt`, `RefreshToken`, |  | ||||||
|         `ConfirmationId`, `ForgotPasswordId`, `OAuthId`, `RefreshTokenExpiryTime`, |  | ||||||
|         `AuthRole`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.FirstName, OLD.LastName, OLD.EMail, OLD.Password, OLD.PasswordSalt, OLD.RefreshToken, |  | ||||||
|         OLD.ConfirmationId, OLD.ForgotPasswordId, OLD.OAuthId, OLD.RefreshTokenExpiryTime, OLD.AuthRole, TRUE, |  | ||||||
|         OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| ALTER TABLE `AutoRoleRules` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `AutoRoleRules` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `AutoRoleRulesHistory` |  | ||||||
| ( |  | ||||||
|     `Id`   BIGINT(20)  NOT NULL, |  | ||||||
|     `AutoRoleId`       BIGINT(20)  DEFAULT NULL, |  | ||||||
|     `DiscordEmojiName` VARCHAR(64) DEFAULT NULL, |  | ||||||
|     `DiscordRoleId`    BIGINT(20)  NOT NULL, |  | ||||||
|     `Deleted`          BOOL        DEFAULT FALSE, |  | ||||||
|     `DateFrom`         DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`           DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AutoRoleRulesUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AutoRoleRulesUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `AutoRoleRules` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AutoRoleRulesHistory` ( |  | ||||||
|         `Id`, `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.AutoRoleRuleId, OLD.AutoRoleId, OLD.DiscordEmojiName, OLD.DiscordRoleId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AutoRoleRulesDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AutoRoleRulesDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `AutoRoleRules` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AutoRoleRulesHistory` ( |  | ||||||
|         `Id`, `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.AutoRoleRuleId, OLD.AutoRoleId, OLD.DiscordEmojiName, OLD.DiscordRoleId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| ALTER TABLE `AutoRoles` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `AutoRoles` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `AutoRolesHistory` |  | ||||||
| ( |  | ||||||
|     `Id`       BIGINT(20)  NOT NULL, |  | ||||||
|     `ServerId`         BIGINT(20) DEFAULT NULL, |  | ||||||
|     `DiscordChannelId` BIGINT(20)  NOT NULL, |  | ||||||
|     `DiscordMessageId` BIGINT(20)  NOT NULL, |  | ||||||
|     `Deleted`          BOOL       DEFAULT FALSE, |  | ||||||
|     `DateFrom`         DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`           DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AutoRolesUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AutoRolesUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `AutoRoles` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AutoRolesHistory` ( |  | ||||||
|         `Id`, `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.AutoRoleId, OLD.ServerId, OLD.DiscordChannelId, OLD.DiscordMessageId, OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_AutoRolesDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_AutoRolesDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `AutoRoles` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `AutoRolesHistory` ( |  | ||||||
|         `Id`, `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.AutoRoleId, OLD.ServerId, OLD.DiscordChannelId, OLD.DiscordMessageId, TRUE, OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,54 +0,0 @@ | |||||||
| ALTER TABLE `Clients` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `Clients` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `ClientsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`              BIGINT(20)  NOT NULL, |  | ||||||
|     `DiscordId`       BIGINT(20)  NOT NULL, |  | ||||||
|     `SentMessageCount`      BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `ReceivedMessageCount`  BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `DeletedMessageCount`   BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `ReceivedCommandsCount` BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `MovedUsersCount`       BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `ServerId`              BIGINT(20)           DEFAULT NULL, |  | ||||||
|     `Deleted`               BOOL                 DEFAULT FALSE, |  | ||||||
|     `DateFrom`              DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`                DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_ClientsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_ClientsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `Clients` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `ClientsHistory` ( |  | ||||||
|         `Id`, `DiscordId`, `SentMessageCount`, `ReceivedMessageCount`, `DeletedMessageCount`, |  | ||||||
|         `ReceivedCommandsCount`, `MovedUsersCount`, `ServerId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.ClientId, OLD.DiscordClientId, OLD.SentMessageCount, OLD.ReceivedMessageCount, OLD.DeletedMessageCount, |  | ||||||
|         OLD.ReceivedCommandsCount, OLD.MovedUsersCount, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_ClientsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_ClientsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `Clients` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `ClientsHistory` ( |  | ||||||
|         `Id`, `DiscordId`, `SentMessageCount`, `ReceivedMessageCount`, `DeletedMessageCount`, |  | ||||||
|         `ReceivedCommandsCount`, `MovedUsersCount`, `ServerId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.ClientId, OLD.DiscordClientId, OLD.SentMessageCount, OLD.ReceivedMessageCount, OLD.DeletedMessageCount, |  | ||||||
|         OLD.ReceivedCommandsCount, OLD.MovedUsersCount, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,57 +0,0 @@ | |||||||
| CREATE TABLE IF NOT EXISTS `CFG_ServerAFKChannelIdsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`    BIGINT(20)  NOT NULL, |  | ||||||
|     `ChannelId` BIGINT NOT NULL, |  | ||||||
|     `ServerId` BIGINT NOT NULL, |  | ||||||
|     `Deleted` BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom` DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo` DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerAFKChannelIdsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_ServerAFKChannelIdsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `CFG_ServerAFKChannelIds` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_ServerAFKChannelIdsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `ChannelId`, |  | ||||||
|         `ServerId`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.ChannelId, |  | ||||||
|         OLD.ServerId, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerAFKChannelIdsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_ServerAFKChannelIdsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `CFG_ServerAFKChannelIds` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_ServerAFKChannelIdsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `ChannelId`, |  | ||||||
|         `ServerId`, |  | ||||||
|         `Deleted`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.ChannelId, |  | ||||||
|         OLD.ServerId, |  | ||||||
|         TRUE, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,62 +0,0 @@ | |||||||
| CREATE TABLE IF NOT EXISTS `CFG_ServerTeamRoleIdsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`    BIGINT(20)  NOT NULL, |  | ||||||
|     `RoleId` BIGINT NOT NULL, |  | ||||||
|     `TeamMemberType` ENUM('Moderator', 'Admin') NOT NULL, |  | ||||||
|     `ServerId` BIGINT NOT NULL, |  | ||||||
|     `Deleted` BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom` DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo` DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerTeamRoleIdsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_ServerTeamRoleIdsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `CFG_ServerTeamRoleIds` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_ServerTeamRoleIdsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `RoleId`, |  | ||||||
|         `TeamMemberType`, |  | ||||||
|         `ServerId`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.RoleId, |  | ||||||
|         OLD.TeamMemberType, |  | ||||||
|         OLD.ServerId, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_ServerTeamRoleIdsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_ServerTeamRoleIdsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `CFG_ServerTeamRoleIds` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_ServerTeamRoleIdsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `RoleId`, |  | ||||||
|         `TeamMemberType`, |  | ||||||
|         `ServerId`, |  | ||||||
|         `Deleted`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.RoleId, |  | ||||||
|         OLD.TeamMemberType, |  | ||||||
|         OLD.ServerId, |  | ||||||
|         TRUE, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,52 +0,0 @@ | |||||||
| CREATE TABLE IF NOT EXISTS `CFG_TechnicianIdsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`    BIGINT(20)  NOT NULL, |  | ||||||
|     `TechnicianId` BIGINT NOT NULL, |  | ||||||
|     `Deleted` BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom` DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo` DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianIdsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_TechnicianIdsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `CFG_TechnicianIds` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_TechnicianIdsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `TechnicianId`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.TechnicianId, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianIdsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_TechnicianIdsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `CFG_TechnicianIds` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_TechnicianIdsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `TechnicianId`, |  | ||||||
|         `Deleted`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.TechnicianId, |  | ||||||
|         TRUE, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,52 +0,0 @@ | |||||||
| CREATE TABLE IF NOT EXISTS `CFG_TechnicianPingUrlsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`    BIGINT(20)  NOT NULL, |  | ||||||
|     `URL` VARCHAR(255) NOT NULL, |  | ||||||
|     `Deleted` BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom` DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo` DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianPingUrlsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_TechnicianPingUrlsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `CFG_TechnicianPingUrls` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_TechnicianPingUrlsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `URL`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.URL, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_CFG_TechnicianPingUrlsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_CFG_TechnicianPingUrlsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `CFG_TechnicianPingUrls` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `CFG_TechnicianPingUrlsHistory` ( |  | ||||||
|         `Id`, |  | ||||||
|         `URL`, |  | ||||||
|         `Deleted`, |  | ||||||
|         `DateFrom`, |  | ||||||
|         `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, |  | ||||||
|         OLD.URL, |  | ||||||
|         TRUE, |  | ||||||
|         OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| ALTER TABLE `GameServers` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `GameServers` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `GameServersHistory` |  | ||||||
| ( |  | ||||||
|     `Id`       BIGINT(20)   NOT NULL, |  | ||||||
|     `Name`     VARCHAR(255) NOT NULL, |  | ||||||
|     `ServerId` BIGINT(20)   NOT NULL, |  | ||||||
|     `ApiKeyId` BIGINT(20)   NOT NULL, |  | ||||||
|     `Deleted`  BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom` DATETIME(6)  NOT NULL, |  | ||||||
|     `DateTo`   DATETIME(6)  NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_GameServersUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_GameServersUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `GameServers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `GameServersHistory` ( |  | ||||||
|         `Id`, `Name`, `ServerId`, `ApiKeyId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Name, OLD.ServerId, OLD.ApiKeyId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_GameServersDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_GameServersDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `GameServers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `GameServersHistory` ( |  | ||||||
|         `Id`, `Name`, `ServerId`, `ApiKeyId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Name, OLD.ServerId, OLD.ApiKeyId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| ALTER TABLE `KnownUsers` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `KnownUsers` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `KnownUsersHistory` |  | ||||||
| ( |  | ||||||
|     `Id` BIGINT(20)  NOT NULL, |  | ||||||
|     `DiscordId`   BIGINT(20)  NOT NULL, |  | ||||||
|     `Deleted`     BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom`    DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`      DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_KnownUsersUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_KnownUsersUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `KnownUsers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `KnownUsersHistory` ( |  | ||||||
|         `Id`, `DiscordId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.KnownUserId, OLD.DiscordId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_KnownUsersDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_KnownUsersDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `KnownUsers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `KnownUsersHistory` ( |  | ||||||
|         `Id`, `DiscordId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.KnownUserId, OLD.DiscordId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,50 +0,0 @@ | |||||||
| ALTER TABLE `Levels` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `Levels` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `LevelsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`            BIGINT(20)   NOT NULL, |  | ||||||
|     `Name`          VARCHAR(255) NOT NULL, |  | ||||||
|     `Color`         VARCHAR(8)   NOT NULL, |  | ||||||
|     `MinXp`         BIGINT(20)   NOT NULL, |  | ||||||
|     `PermissionInt` BIGINT(20)   NOT NULL, |  | ||||||
|     `ServerId`      BIGINT(20) DEFAULT NULL, |  | ||||||
|     `Deleted`       BOOL       DEFAULT FALSE, |  | ||||||
|     `DateFrom`      DATETIME(6)  NOT NULL, |  | ||||||
|     `DateTo`        DATETIME(6)  NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_LevelsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_LevelsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `Levels` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `LevelsHistory` ( |  | ||||||
|         `Id`, `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Name, OLD.Color, OLD.MinXp, OLD.PermissionInt, OLD.ServerId, OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_LevelsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_LevelsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `Levels` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `LevelsHistory` ( |  | ||||||
|         `Id`, `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Name, OLD.Color, OLD.MinXp, OLD.PermissionInt, OLD.ServerId, TRUE, OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| ALTER TABLE `Servers` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `Servers` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `ServersHistory` |  | ||||||
| ( |  | ||||||
|     `Id`        BIGINT(20)  NOT NULL, |  | ||||||
|     `DiscordId` BIGINT(20)  NOT NULL, |  | ||||||
|     `Deleted`         BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom`        DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`          DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_ServersUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_ServersUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `Servers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `ServersHistory` ( |  | ||||||
|         `Id`, `DiscordId`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.ServerId, OLD.DiscordServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_ServersDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_ServersDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `Servers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `ServersHistory` ( |  | ||||||
|         `Id`, `DiscordId`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.ServerId, OLD.DiscordServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| ALTER TABLE `UserGameIdents` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `UserGameIdents` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `UserGameIdentsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`           BIGINT(20)   NOT NULL, |  | ||||||
|     `UserId`       BIGINT(20)   NOT NULL, |  | ||||||
|     `GameServerId` BIGINT(20)   NOT NULL, |  | ||||||
|     `Ident`        VARCHAR(255) NOT NULL, |  | ||||||
|     `Deleted`      BOOL DEFAULT FALSE, |  | ||||||
|     `DateFrom`     DATETIME(6)  NOT NULL, |  | ||||||
|     `DateTo`       DATETIME(6)  NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserGameIdentsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserGameIdentsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `UserGameIdents` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserGameIdentsHistory` ( |  | ||||||
|         `Id`, `UserId`, `GameServerId`, `Ident`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.UserId, OLD.GameServerId, OLD.Ident, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserGameIdentsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserGameIdentsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `UserGameIdents` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserGameIdentsHistory` ( |  | ||||||
|         `Id`, `UserId`, `GameServerId`, `Ident`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.UserId, OLD.GameServerId, OLD.Ident, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| ALTER TABLE `UserJoinedGameServer` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `UserJoinedGameServer` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `UserJoinedGameServerHistory` |  | ||||||
| ( |  | ||||||
|     `Id`           BIGINT(20)  NOT NULL, |  | ||||||
|     `UserId`       BIGINT(20)  NOT NULL, |  | ||||||
|     `GameServerId` BIGINT(20)  NOT NULL, |  | ||||||
|     `JoinedOn`     DATETIME(6) NOT NULL, |  | ||||||
|     `LeavedOn`     DATETIME(6) DEFAULT NULL, |  | ||||||
|     `Deleted`      BOOL        DEFAULT FALSE, |  | ||||||
|     `DateFrom`     DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`       DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserJoinedGameServerUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserJoinedGameServerUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `UserJoinedGameServer` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserJoinedGameServerHistory` ( |  | ||||||
|         `Id`, `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.UserId, OLD.GameServerId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserJoinedGameServerDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserJoinedGameServerDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `UserJoinedGameServer` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserJoinedGameServerHistory` ( |  | ||||||
|         `Id`, `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.UserId, OLD.GameServerId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| ALTER TABLE `UserJoinedServers` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `UserJoinedServers` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `UserJoinedServersHistory` |  | ||||||
| ( |  | ||||||
|     `Id`   BIGINT(20)  NOT NULL, |  | ||||||
|     `UserId`   BIGINT(20)  NOT NULL, |  | ||||||
|     `JoinedOn` DATETIME(6) NOT NULL, |  | ||||||
|     `LeavedOn` DATETIME(6) DEFAULT NULL, |  | ||||||
|     `Deleted`  BOOL        DEFAULT FALSE, |  | ||||||
|     `DateFrom` DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`   DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserJoinedServersUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserJoinedServersUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `UserJoinedServers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserJoinedServersHistory` ( |  | ||||||
|         `Id`, `UserId`, `JoinedOn`, `LeavedOn`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.JoinId, OLD.UserId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserJoinedServersDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserJoinedServersDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `UserJoinedServers` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserJoinedServersHistory` ( |  | ||||||
|         `Id`, `UserId`, `JoinedOn`, `LeavedOn`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.JoinId, OLD.UserId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,49 +0,0 @@ | |||||||
| ALTER TABLE `UserJoinedVoiceChannel` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `UserJoinedVoiceChannel` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `UserJoinedVoiceChannelHistory` |  | ||||||
| ( |  | ||||||
|     `Id`           BIGINT(20)  NOT NULL, |  | ||||||
|     `UserId`           BIGINT(20)  NOT NULL, |  | ||||||
|     `DiscordChannelId` BIGINT(20)  NOT NULL, |  | ||||||
|     `JoinedOn`         DATETIME(6) NOT NULL, |  | ||||||
|     `LeavedOn`         DATETIME(6) DEFAULT NULL, |  | ||||||
|     `Deleted`          BOOL        DEFAULT FALSE, |  | ||||||
|     `DateFrom`         DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`           DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserJoinedVoiceChannelUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserJoinedVoiceChannelUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `UserJoinedVoiceChannel` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserJoinedVoiceChannelHistory` ( |  | ||||||
|         `Id`, `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.JoinId, OLD.UserId, OLD.DiscordChannelId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserJoinedVoiceChannelDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserJoinedVoiceChannelDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `UserJoinedVoiceChannel` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserJoinedVoiceChannelHistory` ( |  | ||||||
|         `Id`, `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.JoinId, OLD.UserId, OLD.DiscordChannelId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt, |  | ||||||
|         CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| ALTER TABLE `UserMessageCountPerHour` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `UserMessageCountPerHour` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `UserMessageCountPerHourHistory` |  | ||||||
| ( |  | ||||||
|     `Id`       BIGINT(20)  NOT NULL, |  | ||||||
|     `Date`     DATETIME(6) NOT NULL, |  | ||||||
|     `Hour`     BIGINT(20) DEFAULT NULL, |  | ||||||
|     `XPCount`  BIGINT(20) DEFAULT NULL, |  | ||||||
|     `UserId`   BIGINT(20) DEFAULT NULL, |  | ||||||
|     `Deleted`  BOOL       DEFAULT FALSE, |  | ||||||
|     `DateFrom` DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`   DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserMessageCountPerHourUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserMessageCountPerHourUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `UserMessageCountPerHour` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserMessageCountPerHourHistory` ( |  | ||||||
|         `Id`, `UserId`, `Date`, `Hour`, `XPCount`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.UserId, OLD.Date, OLD.Hour, OLD.XPCount, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserMessageCountPerHourDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserMessageCountPerHourDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `UserMessageCountPerHour` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserMessageCountPerHourHistory` ( |  | ||||||
|         `Id`, `UserId`, `Date`, `Hour`, `XPCount`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.UserId, OLD.Date, OLD.Hour, OLD.XPCount, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| ALTER TABLE `UserWarnings` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `UserWarnings` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `UserWarningsHistory` |  | ||||||
| ( |  | ||||||
|     `Id`          BIGINT(20)   NOT NULL, |  | ||||||
|     `Description` VARCHAR(255) NOT NULL, |  | ||||||
|     `UserId`      BIGINT(20)   NOT NULL, |  | ||||||
|     `Author`      BIGINT(20) DEFAULT NULL, |  | ||||||
|     `Deleted`     BOOL       DEFAULT FALSE, |  | ||||||
|     `DateFrom`    DATETIME(6)  NOT NULL, |  | ||||||
|     `DateTo`      DATETIME(6)  NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserWarningsUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserWarningsUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `UserWarnings` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserWarningsHistory` ( |  | ||||||
|         `Id`, `Description`, `UserId`, `Author`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Description, OLD.UserId, OLD.Author, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UserWarningsDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UserWarningsDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `UserWarnings` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UserWarningsHistory` ( |  | ||||||
|         `Id`, `Description`, `UserId`, `Author`, `Deleted`, `DateFrom`, `DateTo` |  | ||||||
|     ) |  | ||||||
|     VALUES ( |  | ||||||
|         OLD.Id, OLD.Description, OLD.UserId, OLD.Author, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6) |  | ||||||
|     ); |  | ||||||
| END; |  | ||||||
| @@ -1,45 +0,0 @@ | |||||||
| ALTER TABLE `Users` |  | ||||||
|     CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| ALTER TABLE `Users` |  | ||||||
|     CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6); |  | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS `UsersHistory` |  | ||||||
| ( |  | ||||||
|     `Id`            BIGINT(20)  NOT NULL, |  | ||||||
|     `DiscordId`     BIGINT(20)  NOT NULL, |  | ||||||
|     `XP`            BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `ReactionCount` BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `MessageCount`  BIGINT(20)  NOT NULL DEFAULT 0, |  | ||||||
|     `Birthday`      DATE        NULL, |  | ||||||
|     `ServerId`      BIGINT(20)           DEFAULT NULL, |  | ||||||
|     `Deleted`       BOOL                 DEFAULT FALSE, |  | ||||||
|     `DateFrom`      DATETIME(6) NOT NULL, |  | ||||||
|     `DateTo`        DATETIME(6) NOT NULL |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UsersUpdate`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UsersUpdate` |  | ||||||
|     AFTER UPDATE |  | ||||||
|     ON `Users` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UsersHistory` (`Id`, `DiscordId`, `XP`, `ReactionCount`, `MessageCount`, `Birthday`, `ServerId`, |  | ||||||
|                                 `DateFrom`, `DateTo`) |  | ||||||
|     VALUES (OLD.UserId, OLD.DiscordId, OLD.XP, OLD.ReactionCount, OLD.MessageCount, OLD.Birthday, OLD.ServerId, |  | ||||||
|             OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); |  | ||||||
| END; |  | ||||||
|  |  | ||||||
| DROP TRIGGER IF EXISTS `TR_UsersDelete`; |  | ||||||
|  |  | ||||||
| CREATE TRIGGER `TR_UsersDelete` |  | ||||||
|     AFTER DELETE |  | ||||||
|     ON `Users` |  | ||||||
|     FOR EACH ROW |  | ||||||
| BEGIN |  | ||||||
|     INSERT INTO `UsersHistory` (`Id`, `DiscordId`, `XP`, `ReactionCount`, `MessageCount`, `Birthday`, `ServerId`, |  | ||||||
|                                 `Deleted`, `DateFrom`, `DateTo`) |  | ||||||
|     VALUES (OLD.UserId, OLD.DiscordId, OLD.XP, OLD.ReactionCount, OLD.MessageCount, OLD.Birthday, OLD.ServerId, TRUE, |  | ||||||
|             OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)); |  | ||||||
| END; |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class DefaultRoleMigration(MigrationABC): |  | ||||||
|     name = "1.1.3_DefaultRoleMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Server |  | ||||||
|                     ADD DefaultRoleId BIGINT NULL AFTER LoginMessageChannelId; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Server DROP COLUMN DefaultRoleId; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| @@ -1,51 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class FixUpdatesMigration(MigrationABC): |  | ||||||
|     name = "1.1.7_FixUpdatesMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_ServerHistory |  | ||||||
|                     ADD DefaultRoleId BIGINT NULL AFTER LoginMessageChannelId; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 """ALTER TABLE CFG_TechnicianHistory ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;""" |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 """ALTER TABLE CFG_ServerHistory ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;""" |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._exec(__file__, "config/server.sql") |  | ||||||
|         self._exec(__file__, "config/technician.sql") |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_ServerHistory DROP COLUMN DefaultRoleId; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute("ALTER TABLE CFG_TechnicianHistory DROP COLUMN FeatureFlags;") |  | ||||||
|         self._cursor.execute("ALTER TABLE CFG_ServerHistory DROP COLUMN FeatureFlags;") |  | ||||||
| @@ -1,41 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class FixUserHistoryMigration(MigrationABC): |  | ||||||
|     name = "1.2.0_FixUserHistoryMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         # fix 1.1.0_AchievementsMigration |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str(f"""ALTER TABLE UsersHistory ADD COLUMN ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;""") |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str(f"""ALTER TABLE UsersHistory ADD COLUMN MessageCount BIGINT NOT NULL DEFAULT 0 AFTER ReactionCount;""") |  | ||||||
|         ) |  | ||||||
|         self._exec(__file__, "users.sql") |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE UsersHistory DROP COLUMN MessageCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE UsersHistory DROP COLUMN ReactionCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| @@ -1,138 +0,0 @@ | |||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.migration_abc import MigrationABC |  | ||||||
| from bot_data.db_context import DBContext |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class InitialMigration(MigrationABC): |  | ||||||
|     name = "0.1_InitialMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `MigrationHistory` ( |  | ||||||
|                 `MigrationId` VARCHAR(255), |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 PRIMARY KEY(`MigrationId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `Servers` ( |  | ||||||
|                 `ServerId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `DiscordServerId` BIGINT NOT NULL, |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 PRIMARY KEY(`ServerId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `Users` ( |  | ||||||
|                 `UserId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `DiscordId` BIGINT NOT NULL, |  | ||||||
|                 `XP` BIGINT NOT NULL DEFAULT 0, |  | ||||||
|                 `ServerId` BIGINT, |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 FOREIGN KEY (`ServerId`) REFERENCES Servers(`ServerId`), |  | ||||||
|                 PRIMARY KEY(`UserId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `Clients` ( |  | ||||||
|                 `ClientId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `DiscordClientId` BIGINT NOT NULL, |  | ||||||
|                 `SentMessageCount` BIGINT NOT NULL DEFAULT 0, |  | ||||||
|                 `ReceivedMessageCount` BIGINT NOT NULL DEFAULT 0, |  | ||||||
|                 `DeletedMessageCount` BIGINT NOT NULL DEFAULT 0, |  | ||||||
|                 `ReceivedCommandsCount` BIGINT NOT NULL DEFAULT 0, |  | ||||||
|                 `MovedUsersCount` BIGINT NOT NULL DEFAULT 0, |  | ||||||
|                 `ServerId` BIGINT, |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 FOREIGN KEY (`ServerId`) REFERENCES Servers(`ServerId`), |  | ||||||
|                 PRIMARY KEY(`ClientId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `KnownUsers` ( |  | ||||||
|                 `KnownUserId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `DiscordId` BIGINT NOT NULL, |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 PRIMARY KEY(`KnownUserId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `UserJoinedServers` ( |  | ||||||
|                 `JoinId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `UserId` BIGINT NOT NULL, |  | ||||||
|                 `JoinedOn` DATETIME(6) NOT NULL, |  | ||||||
|                 `LeavedOn` DATETIME(6), |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 FOREIGN KEY (`UserId`) REFERENCES Users(`UserId`), |  | ||||||
|                 PRIMARY KEY(`JoinId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|             CREATE TABLE IF NOT EXISTS `UserJoinedVoiceChannel` ( |  | ||||||
|                 `JoinId` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                 `UserId` BIGINT NOT NULL, |  | ||||||
|                 `DiscordChannelId` BIGINT NOT NULL, |  | ||||||
|                 `JoinedOn` DATETIME(6) NOT NULL, |  | ||||||
|                 `LeavedOn` DATETIME(6), |  | ||||||
|                 `CreatedAt` DATETIME(6), |  | ||||||
|                 `LastModifiedAt` DATETIME(6), |  | ||||||
|                 FOREIGN KEY (`UserId`) REFERENCES Users(`UserId`), |  | ||||||
|                 PRIMARY KEY(`JoinId`) |  | ||||||
|             ); |  | ||||||
|             """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `Servers`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `Users`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `Clients`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `KnownUsers`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserJoinedServers`;") |  | ||||||
|         self._cursor.execute("DROP TABLE `UserJoinedVoiceChannel`;") |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user