Compare commits
	
		
			6 Commits
		
	
	
		
			1.2.0
			...
			b175b07e35
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b175b07e35 | |||
| ec8f15fd72 | |||
| 65a09c428d | |||
| 1125c83d13 | |||
| 76d94c0f60 | |||
| eb3eb24e81 | 
| @@ -8,56 +8,50 @@ on: | |||||||
| jobs: | jobs: | ||||||
|   on-push-deploy_sh-edraft: |   on-push-deploy_sh-edraft: | ||||||
|     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|     container: sh-edraft.de/act-runner:latest |     container: catthehacker/ubuntu:act-latest | ||||||
|     steps: |     steps: | ||||||
|  |       - name: Setup Python 3.10 | ||||||
|  |         uses: actions/setup-python@v3 | ||||||
|  |         with: | ||||||
|  |           python-version: "3.10.12" | ||||||
|  |       - run: python -v | ||||||
|  |  | ||||||
|       - name: Setup docker |       - name: Setup docker | ||||||
|         uses: https://github.com/papodaca/install-docker-action@main |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
|       - run: docker -v |       - run: docker -v | ||||||
|  |  | ||||||
|       - name: Clone Repository |       - name: Clone Repository | ||||||
|         uses: https://github.com/actions/checkout@v3 |         uses: https://github.com/actions/checkout@v3 | ||||||
|         with: |  | ||||||
|           token: ${{ secrets.CI_ACCESS_TOKEN }} |       - name: Shutdown stack | ||||||
|           submodules: true |         run: docker stack rm kdb_staging | ||||||
|  |  | ||||||
|       - name: Prepare bot build |       - name: Prepare bot build | ||||||
|         run: | |         run: | | ||||||
|           cd bot |           cd kdb-bot | ||||||
|           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli |           pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|           cpl i |           cpl i | ||||||
|  |  | ||||||
|  |       - name: Build docker bot | ||||||
|  |         run: | | ||||||
|  |           cd kdb-bot | ||||||
|  |           docker image prune -f | ||||||
|  |           cpl docker-build | ||||||
|  |  | ||||||
|       - name: Setup node |       - name: Setup node | ||||||
|         uses: https://github.com/actions/setup-node@v3 |         uses: https://github.com/actions/setup-node@v3 | ||||||
|  |  | ||||||
|       - name: Prepare web build |       - name: Prepare web build | ||||||
|         run: | |         run: | | ||||||
|           cd web |           cd kdb-web | ||||||
|           npm install -g ts-node |           npm install -g ts-node | ||||||
|           npm ci |           npm i | ||||||
|  |  | ||||||
|       - name: 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 kdb-web | ||||||
|           docker image prune -f |           docker image prune -f | ||||||
|           cp src/favicon.dev.ico src/favicon.ico |           npm run docker-build | ||||||
|           npm run build |  | ||||||
|           docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-dev . |  | ||||||
|  |  | ||||||
|       - name: Set version |  | ||||||
|         run: | |  | ||||||
|           cd bot/docker |  | ||||||
|           chmod +x ./set-docker-compose-image-version.sh |  | ||||||
|           ./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-dev sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-dev |  | ||||||
|  |  | ||||||
|       - name: Deploy Stack to sh-edraft.de |       - 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 | ||||||
| @@ -66,6 +60,6 @@ jobs: | |||||||
|           portainer-username: "gitea_job" |           portainer-username: "gitea_job" | ||||||
|           portainer-password: "${{ secrets.docker_job }}" |           portainer-password: "${{ secrets.docker_job }}" | ||||||
|           portainer-endpoint: 2 |           portainer-endpoint: 2 | ||||||
|           name: sdb_dev |           name: kdb_staging | ||||||
|           file: bot/docker/docker-compose.dev.yml |           file: ./docker-compose.staging.yml | ||||||
|           variables: '{}' |           variables: '{}' | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| name: Deploy prod on push | name: Deploy dev on push | ||||||
| run-name: Deploy prod on push | run-name: Deploy dev on push | ||||||
| on: | on: | ||||||
|   push: |   push: | ||||||
|     branches: |     branches: | ||||||
| @@ -8,55 +8,50 @@ on: | |||||||
| jobs: | jobs: | ||||||
|   on-push-deploy_sh-edraft: |   on-push-deploy_sh-edraft: | ||||||
|     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] |     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] | ||||||
|     container: sh-edraft.de/act-runner:latest |     container: catthehacker/ubuntu:act-latest | ||||||
|     steps: |     steps: | ||||||
|  |       - name: Setup Python 3.10 | ||||||
|  |         uses: actions/setup-python@v3 | ||||||
|  |         with: | ||||||
|  |           python-version: "3.10.12" | ||||||
|  |       - run: python -v | ||||||
|  |  | ||||||
|       - name: Setup docker |       - name: Setup docker | ||||||
|         uses: https://github.com/papodaca/install-docker-action@main |         uses: https://github.com/papodaca/install-docker-action@main | ||||||
|       - run: docker -v |       - run: docker -v | ||||||
|  |  | ||||||
|       - name: Clone Repository |       - name: Clone Repository | ||||||
|         uses: https://github.com/actions/checkout@v3 |         uses: https://github.com/actions/checkout@v3 | ||||||
|         with: |  | ||||||
|           token: ${{ secrets.CI_ACCESS_TOKEN }} |       - name: Shutdown stack | ||||||
|           submodules: true |         run: docker stack rm kdb_prod | ||||||
|  |  | ||||||
|       - name: Prepare bot build |       - name: Prepare bot build | ||||||
|         run: | |         run: | | ||||||
|           cd bot |           cd kdb-bot | ||||||
|           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli |           pip install --extra-index-url https://pip.sh-edraft.de cpl-cli | ||||||
|           cpl i |           cpl i | ||||||
|  |  | ||||||
|  |       - name: Build docker bot | ||||||
|  |         run: | | ||||||
|  |           cd kdb-bot | ||||||
|  |           docker image prune -f | ||||||
|  |           cpl docker-build | ||||||
|  |  | ||||||
|       - name: Setup node |       - name: Setup node | ||||||
|         uses: https://github.com/actions/setup-node@v3 |         uses: https://github.com/actions/setup-node@v3 | ||||||
|  |  | ||||||
|       - name: Prepare web build |       - name: Prepare web build | ||||||
|         run: | |         run: | | ||||||
|           cd web |           cd kdb-web | ||||||
|           npm install -g ts-node |           npm install -g ts-node | ||||||
|           npm ci |           npm i | ||||||
|  |  | ||||||
|       - name: 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 kdb-web | ||||||
|           docker image prune -f |           docker image prune -f | ||||||
|           npm run build |           npm run docker-build | ||||||
|           docker build -t sh-edraft.de/sdb-web:$(npm run -s gv) . |  | ||||||
|  |  | ||||||
|       - name: Set version |  | ||||||
|         run: | |  | ||||||
|           cd bot/docker |  | ||||||
|           chmod +x ./set-docker-compose-image-version.sh |  | ||||||
|           ./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv) sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;) |  | ||||||
|  |  | ||||||
|       - name: Deploy Stack to sh-edraft.de |       - 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 | ||||||
| @@ -65,6 +60,6 @@ jobs: | |||||||
|           portainer-username: "gitea_job" |           portainer-username: "gitea_job" | ||||||
|           portainer-password: "${{ secrets.docker_job }}" |           portainer-password: "${{ secrets.docker_job }}" | ||||||
|           portainer-endpoint: 2 |           portainer-endpoint: 2 | ||||||
|           name: sdb_prod |           name: kdb_prod | ||||||
|           file: bot/docker/docker-compose.yml |           file: ./docker-compose.yml | ||||||
|           variables: '{}' |           variables: '{}' | ||||||
|   | |||||||
| @@ -1,71 +0,0 @@ | |||||||
| name: Deploy staging on push |  | ||||||
| run-name: Deploy staging on push |  | ||||||
| on: |  | ||||||
|   push: |  | ||||||
|     branches: |  | ||||||
|       - staging |  | ||||||
|  |  | ||||||
| jobs: |  | ||||||
|   on-push-deploy_sh-edraft: |  | ||||||
|     runs-on: [ dobby.sh-edraft.de, ubuntu-latest ] |  | ||||||
|     container: sh-edraft.de/act-runner:latest |  | ||||||
|     steps: |  | ||||||
|       - name: Setup docker |  | ||||||
|         uses: https://github.com/papodaca/install-docker-action@main |  | ||||||
|       - run: docker -v |  | ||||||
|  |  | ||||||
|       - name: Clone Repository |  | ||||||
|         uses: https://github.com/actions/checkout@v3 |  | ||||||
|         with: |  | ||||||
|           token: ${{ secrets.CI_ACCESS_TOKEN }} |  | ||||||
|           submodules: true |  | ||||||
|  |  | ||||||
|       - name: Prepare bot build |  | ||||||
|         run: | |  | ||||||
|           cd bot |  | ||||||
|           python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli |  | ||||||
|           cpl i |  | ||||||
|  |  | ||||||
|       - name: Setup node |  | ||||||
|         uses: https://github.com/actions/setup-node@v3 |  | ||||||
|  |  | ||||||
|       - name: Prepare web build |  | ||||||
|         run: | |  | ||||||
|           cd web |  | ||||||
|           npm install -g ts-node |  | ||||||
|           npm ci |  | ||||||
|  |  | ||||||
|       - name: Shutdown stack |  | ||||||
|         run: docker stack rm sdb_staging |  | ||||||
|  |  | ||||||
|       - name: Build docker bot |  | ||||||
|         run: | |  | ||||||
|           cd bot |  | ||||||
|           docker image prune -f |  | ||||||
|           cpl build |  | ||||||
|           docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-staging . |  | ||||||
|  |  | ||||||
|       - name: Build docker web |  | ||||||
|         run: | |  | ||||||
|           cd web |  | ||||||
|           docker image prune -f |  | ||||||
|           cp src/favicon.staging.ico src/favicon.ico |  | ||||||
|           npm run build |  | ||||||
|           docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-staging . |  | ||||||
|  |  | ||||||
|       - name: Set version |  | ||||||
|         run: | |  | ||||||
|           cd bot/docker |  | ||||||
|           chmod +x ./set-docker-compose-image-version.sh |  | ||||||
|           ./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-staging sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-staging |  | ||||||
|  |  | ||||||
|       - name: Deploy Stack to sh-edraft.de |  | ||||||
|         uses: https://github.com/kgierke/portainer-stack-deployment@v1 |  | ||||||
|         with: |  | ||||||
|           portainer-url: "https://docker.sh-edraft.de" |  | ||||||
|           portainer-username: "gitea_job" |  | ||||||
|           portainer-password: "${{ secrets.docker_job }}" |  | ||||||
|           portainer-endpoint: 2 |  | ||||||
|           name: sdb_staging |  | ||||||
|           file: bot/docker/docker-compose.staging.yml |  | ||||||
|           variables: '{}' |  | ||||||
							
								
								
									
										18
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,9 +1,9 @@ | |||||||
| [submodule "bot/src/bot/config"] | [submodule "kdb-bot/src/bot/config"] | ||||||
| 	path = bot/src/bot/config | 	path = kdb-bot/src/bot/config | ||||||
| 	url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.config.git | 	url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.config.git | ||||||
| [submodule "bot/src/bot_api/config"] | [submodule "kdb-bot/src/bot_api/config"] | ||||||
| 	path = bot/src/bot_api/config | 	path = kdb-bot/src/bot_api/config | ||||||
| 	url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.api.config.git | 	url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.api.config.git | ||||||
| [submodule "bot/docker"] | [submodule "kdb-bot/docker"] | ||||||
| 	path = bot/docker | 	path = kdb-bot/docker | ||||||
| 	url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.docker.git | 	url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.docker.git | ||||||
|   | |||||||
 Submodule bot/docker deleted from 9c0dc59534
									
								
							 Submodule bot/src/bot/config deleted from c11ca6f2e8
									
								
							 Submodule bot/src/bot_api/config deleted from 521951b8ab
									
								
							| @@ -1,33 +0,0 @@ | |||||||
| import asyncio |  | ||||||
| from abc import abstractmethod |  | ||||||
|  |  | ||||||
| from cpl_core.configuration import ConfigurationABC |  | ||||||
| from cpl_core.dependency_injection import ServiceProviderABC |  | ||||||
| from cpl_discord.service import DiscordBotServiceABC |  | ||||||
| from discord.ext import commands |  | ||||||
|  |  | ||||||
| from bot_core.environment_variables import MAINTENANCE |  | ||||||
| from bot_core.logging.task_logger import TaskLogger |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class TaskABC(commands.Cog): |  | ||||||
|     @abstractmethod |  | ||||||
|     def __init__(self): |  | ||||||
|         commands.Cog.__init__(self) |  | ||||||
|  |  | ||||||
|     @ServiceProviderABC.inject |  | ||||||
|     def _is_maintenance(self, config: ConfigurationABC) -> bool: |  | ||||||
|         return config.get_configuration(MAINTENANCE) is True |  | ||||||
|  |  | ||||||
|     @ServiceProviderABC.inject |  | ||||||
|     async def _wait_until_ready(self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC): |  | ||||||
|         logger.debug(__name__, f"Waiting before {type(self).__name__}") |  | ||||||
|         await bot.wait_until_ready() |  | ||||||
|  |  | ||||||
|         async def wait(): |  | ||||||
|             is_ready = config.get_configuration("IS_READY") is True |  | ||||||
|             if not is_ready: |  | ||||||
|                 await asyncio.sleep(1) |  | ||||||
|                 await wait() |  | ||||||
|  |  | ||||||
|         await wait() |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| MIGRATION_ONLY = "MIGRATION_ONLY" |  | ||||||
| MAINTENANCE = "MAINTENANCE" |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| from cpl_core.configuration import ConfigurationABC |  | ||||||
| from cpl_core.environment import ApplicationEnvironmentABC |  | ||||||
| from cpl_core.time import TimeFormatSettings |  | ||||||
|  |  | ||||||
| from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class TaskLogger(CustomFileLoggerABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         config: ConfigurationABC, |  | ||||||
|         time_format: TimeFormatSettings, |  | ||||||
|         env: ApplicationEnvironmentABC, |  | ||||||
|     ): |  | ||||||
|         CustomFileLoggerABC.__init__(self, "Task", config, time_format, env) |  | ||||||
| @@ -1,32 +0,0 @@ | |||||||
| from abc import ABC, abstractmethod |  | ||||||
| from typing import Optional |  | ||||||
|  |  | ||||||
| from cpl_query.extension import List |  | ||||||
|  |  | ||||||
| from bot_data.model.steam_special_offer import SteamSpecialOffer |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SteamSpecialOfferRepositoryABC(ABC): |  | ||||||
|     @abstractmethod |  | ||||||
|     def __init__(self): |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     @abstractmethod |  | ||||||
|     def get_steam_special_offers(self) -> List[SteamSpecialOffer]: |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     @abstractmethod |  | ||||||
|     def get_steam_special_offer_by_name(self, name: str) -> SteamSpecialOffer: |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     @abstractmethod |  | ||||||
|     def add_steam_special_offer(self, steam_special_offer: SteamSpecialOffer): |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     @abstractmethod |  | ||||||
|     def update_steam_special_offer(self, steam_special_offer: SteamSpecialOffer): |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     @abstractmethod |  | ||||||
|     def delete_steam_special_offer(self, steam_special_offer: SteamSpecialOffer): |  | ||||||
|         pass |  | ||||||
| @@ -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,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,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,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 MaintenanceModeMigration(MigrationABC): |  | ||||||
|     name = "1.2.0_MaintenanceModeMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Technician |  | ||||||
|                     ADD Maintenance BOOLEAN DEFAULT FALSE AFTER MaxSteamOfferCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_TechnicianHistory |  | ||||||
|                     ADD Maintenance BOOLEAN DEFAULT FALSE AFTER MaxSteamOfferCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._exec(__file__, "config/technician.sql") |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Technician DROP COLUMN Maintenance; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_TechnicianHistory DROP COLUMN Maintenance; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| @@ -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 MaxSteamOfferCountMigration(MigrationABC): |  | ||||||
|     name = "1.2.0_MaxSteamOfferCountMigration" |  | ||||||
|  |  | ||||||
|     def __init__(self, logger: DatabaseLogger, db: DBContext): |  | ||||||
|         MigrationABC.__init__(self) |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._cursor = db.cursor |  | ||||||
|  |  | ||||||
|     def upgrade(self): |  | ||||||
|         self._logger.debug(__name__, "Running upgrade") |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Technician |  | ||||||
|                     ADD MaxSteamOfferCount BIGINT NOT NULL DEFAULT 250 AFTER CacheMaxMessages; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_TechnicianHistory |  | ||||||
|                     ADD MaxSteamOfferCount BIGINT NOT NULL DEFAULT 250 AFTER CacheMaxMessages; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._exec(__file__, "config/technician.sql") |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Technician DROP COLUMN MaxSteamOfferCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_TechnicianHistory DROP COLUMN MaxSteamOfferCount; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| @@ -1,68 +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 SteamSpecialOfferMigration(MigrationABC): |  | ||||||
|     name = "1.2.0_SteamSpecialOfferMigration" |  | ||||||
|  |  | ||||||
|     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 `SteamSpecialOffers` ( |  | ||||||
|                         `Id` BIGINT NOT NULL AUTO_INCREMENT, |  | ||||||
|                         `Game` VARCHAR(255) NOT NULL, |  | ||||||
|                         `OriginalPrice` FLOAT NOT NULL, |  | ||||||
|                         `DiscountPrice` FLOAT NOT NULL, |  | ||||||
|                         `DiscountPct` 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`) |  | ||||||
|                     ); |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Server |  | ||||||
|                     ADD COLUMN GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_ServerHistory |  | ||||||
|                     ADD COLUMN GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def downgrade(self): |  | ||||||
|         self._cursor.execute("DROP TABLE `SteamSpecialOffers`;") |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_Server DROP COLUMN ShortRoleNameSetOnlyHighest; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         self._cursor.execute( |  | ||||||
|             str( |  | ||||||
|                 f""" |  | ||||||
|                     ALTER TABLE CFG_ServerHistory DROP COLUMN ShortRoleNameSetOnlyHighest; |  | ||||||
|                 """ |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| @@ -1,115 +0,0 @@ | |||||||
| from datetime import datetime |  | ||||||
|  |  | ||||||
| from cpl_core.database import TableABC |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SteamSpecialOffer(TableABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         name: str, |  | ||||||
|         original_price: float, |  | ||||||
|         discount_price: float, |  | ||||||
|         discount_pct: int, |  | ||||||
|         created_at: datetime = None, |  | ||||||
|         modified_at: datetime = None, |  | ||||||
|         id=0, |  | ||||||
|     ): |  | ||||||
|         self._id = id |  | ||||||
|         self._name = name |  | ||||||
|         self._original_price = original_price |  | ||||||
|         self._discount_price = discount_price |  | ||||||
|         self._discount_pct = discount_pct |  | ||||||
|  |  | ||||||
|         TableABC.__init__(self) |  | ||||||
|         self._created_at = created_at if created_at is not None else self._created_at |  | ||||||
|         self._modified_at = modified_at if modified_at is not None else self._modified_at |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def id(self) -> int: |  | ||||||
|         return self._id |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def name(self) -> str: |  | ||||||
|         return self._name |  | ||||||
|  |  | ||||||
|     @name.setter |  | ||||||
|     def name(self, value: str): |  | ||||||
|         self._name = value |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def original_price(self) -> float: |  | ||||||
|         return self._original_price |  | ||||||
|  |  | ||||||
|     @original_price.setter |  | ||||||
|     def original_price(self, value: float): |  | ||||||
|         self._original_price = value |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def discount_price(self) -> float: |  | ||||||
|         return self._discount_price |  | ||||||
|  |  | ||||||
|     @discount_price.setter |  | ||||||
|     def discount_price(self, value: float): |  | ||||||
|         self._discount_price = value |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def discount_pct(self) -> int: |  | ||||||
|         return self._discount_pct |  | ||||||
|  |  | ||||||
|     @discount_pct.setter |  | ||||||
|     def discount_pct(self, value: int): |  | ||||||
|         self._discount_pct = value |  | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def get_select_all_string() -> str: |  | ||||||
|         return str( |  | ||||||
|             f""" |  | ||||||
|             SELECT * FROM `SteamSpecialOffers`; |  | ||||||
|         """ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def get_select_by_name_string(name: str) -> str: |  | ||||||
|         return str( |  | ||||||
|             f""" |  | ||||||
|             SELECT * FROM `SteamSpecialOffers` |  | ||||||
|             WHERE `Game` = '{name}'; |  | ||||||
|         """ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def insert_string(self) -> str: |  | ||||||
|         return str( |  | ||||||
|             f""" |  | ||||||
|             INSERT INTO `SteamSpecialOffers` ( |  | ||||||
|                 `Game`, `OriginalPrice`, `DiscountPrice`, `DiscountPct` |  | ||||||
|             ) VALUES ( |  | ||||||
|                 '{self._name}', |  | ||||||
|                 {self._original_price}, |  | ||||||
|                 {self._discount_price}, |  | ||||||
|                 {self._discount_pct} |  | ||||||
|             ); |  | ||||||
|         """ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def udpate_string(self) -> str: |  | ||||||
|         return str( |  | ||||||
|             f""" |  | ||||||
|             UPDATE `SteamSpecialOffers` |  | ||||||
|             SET `Game` = '{self._name}', |  | ||||||
|             `OriginalPrice` = {self._original_price}, |  | ||||||
|             `DiscountPrice` = {self._discount_price}, |  | ||||||
|             `DiscountPct` = {self._discount_pct} |  | ||||||
|             WHERE `Id` = {self._id}; |  | ||||||
|         """ |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def delete_string(self) -> str: |  | ||||||
|         return str( |  | ||||||
|             f""" |  | ||||||
|             DELETE FROM `SteamSpecialOffers` |  | ||||||
|             WHERE `Id` = {self._id}; |  | ||||||
|         """ |  | ||||||
|         ) |  | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| from typing import Optional |  | ||||||
|  |  | ||||||
| from bot_data.abc.history_table_abc import HistoryTableABC |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # had to name it UserWarnings instead of UserWarning because UserWarning is a builtin class |  | ||||||
| class UserWarningsHistory(HistoryTableABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         description: str, |  | ||||||
|         user: int, |  | ||||||
|         author: Optional[int], |  | ||||||
|         deleted: bool, |  | ||||||
|         date_from: str, |  | ||||||
|         date_to: str, |  | ||||||
|         id=0, |  | ||||||
|     ): |  | ||||||
|         HistoryTableABC.__init__(self) |  | ||||||
|  |  | ||||||
|         self._id = id |  | ||||||
|         self._description = description |  | ||||||
|         self._user = user |  | ||||||
|         self._author = author |  | ||||||
|  |  | ||||||
|         self._deleted = deleted |  | ||||||
|         self._date_from = date_from |  | ||||||
|         self._date_to = date_to |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def id(self) -> int: |  | ||||||
|         return self._id |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def description(self) -> str: |  | ||||||
|         return self._description |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def user(self) -> int: |  | ||||||
|         return self._user |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def author(self) -> Optional[int]: |  | ||||||
|         return self._author |  | ||||||
| @@ -1,73 +0,0 @@ | |||||||
| from typing import Optional |  | ||||||
|  |  | ||||||
| from cpl_core.database.context import DatabaseContextABC |  | ||||||
| from cpl_query.extension import List |  | ||||||
|  |  | ||||||
| from bot_core.logging.database_logger import DatabaseLogger |  | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC |  | ||||||
| from bot_data.abc.steam_special_offer_repository_abc import ( |  | ||||||
|     SteamSpecialOfferRepositoryABC, |  | ||||||
| ) |  | ||||||
| from bot_data.model.steam_special_offer import SteamSpecialOffer |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SteamSpecialOfferRepositoryService(SteamSpecialOfferRepositoryABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         logger: DatabaseLogger, |  | ||||||
|         db_context: DatabaseContextABC, |  | ||||||
|         servers: ServerRepositoryABC, |  | ||||||
|     ): |  | ||||||
|         self._logger = logger |  | ||||||
|         self._context = db_context |  | ||||||
|  |  | ||||||
|         self._servers = servers |  | ||||||
|  |  | ||||||
|         SteamSpecialOfferRepositoryABC.__init__(self) |  | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def _get_value_from_result(value: any) -> Optional[any]: |  | ||||||
|         if isinstance(value, str) and "NULL" in value: |  | ||||||
|             return None |  | ||||||
|  |  | ||||||
|         return value |  | ||||||
|  |  | ||||||
|     def _steam_special_offer_from_result(self, sql_result: tuple) -> SteamSpecialOffer: |  | ||||||
|         return SteamSpecialOffer( |  | ||||||
|             self._get_value_from_result(sql_result[1]),  # name |  | ||||||
|             float(self._get_value_from_result(sql_result[2])),  # original_price |  | ||||||
|             float(self._get_value_from_result(sql_result[3])),  # discount_price |  | ||||||
|             int(self._get_value_from_result(sql_result[4])),  # discount_pct |  | ||||||
|             id=self._get_value_from_result(sql_result[0]),  # id |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def get_steam_special_offers(self) -> List[SteamSpecialOffer]: |  | ||||||
|         steam_special_offers = List(SteamSpecialOffer) |  | ||||||
|         self._logger.trace(__name__, f"Send SQL command: {SteamSpecialOffer.get_select_all_string()}") |  | ||||||
|         results = self._context.select(SteamSpecialOffer.get_select_all_string()) |  | ||||||
|         for result in results: |  | ||||||
|             self._logger.trace(__name__, f"Get steam_special_offer with id {result[0]}") |  | ||||||
|             steam_special_offers.append(self._steam_special_offer_from_result(result)) |  | ||||||
|  |  | ||||||
|         return steam_special_offers |  | ||||||
|  |  | ||||||
|     def get_steam_special_offer_by_name(self, name: str) -> SteamSpecialOffer: |  | ||||||
|         self._logger.trace( |  | ||||||
|             __name__, |  | ||||||
|             f"Send SQL command: {SteamSpecialOffer.get_select_by_name_string(name)}", |  | ||||||
|         ) |  | ||||||
|         result = self._context.select(SteamSpecialOffer.get_select_by_name_string(name))[0] |  | ||||||
|  |  | ||||||
|         return self._steam_special_offer_from_result(result) |  | ||||||
|  |  | ||||||
|     def add_steam_special_offer(self, steam_special_offer: SteamSpecialOffer): |  | ||||||
|         self._logger.trace(__name__, f"Send SQL command: {steam_special_offer.insert_string}") |  | ||||||
|         self._context.cursor.execute(steam_special_offer.insert_string) |  | ||||||
|  |  | ||||||
|     def update_steam_special_offer(self, steam_special_offer: SteamSpecialOffer): |  | ||||||
|         self._logger.trace(__name__, f"Send SQL command: {steam_special_offer.udpate_string}") |  | ||||||
|         self._context.cursor.execute(steam_special_offer.udpate_string) |  | ||||||
|  |  | ||||||
|     def delete_steam_special_offer(self, steam_special_offer: SteamSpecialOffer): |  | ||||||
|         self._logger.trace(__name__, f"Send SQL command: {steam_special_offer.delete_string}") |  | ||||||
|         self._context.cursor.execute(steam_special_offer.delete_string) |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| from cpl_core.dependency_injection import ServiceProviderABC |  | ||||||
| from cpl_query.extension import List |  | ||||||
|  |  | ||||||
| from bot_data.model.user_warnings import UserWarnings |  | ||||||
| from bot_graphql.abc.filter_abc import FilterABC |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class UserWarningFilter(FilterABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         services: ServiceProviderABC, |  | ||||||
|     ): |  | ||||||
|         FilterABC.__init__(self) |  | ||||||
|  |  | ||||||
|         self._services = services |  | ||||||
|  |  | ||||||
|         self._id = None |  | ||||||
|         self._user = None |  | ||||||
|         self._description = None |  | ||||||
|         self._author = None |  | ||||||
|  |  | ||||||
|     def from_dict(self, values: dict): |  | ||||||
|         if "id" in values: |  | ||||||
|             self._id = int(values["id"]) |  | ||||||
|  |  | ||||||
|         if "user" in values: |  | ||||||
|             from bot_graphql.filter.user_filter import UserFilter |  | ||||||
|  |  | ||||||
|             self._user: UserFilter = self._services.get_service(UserFilter) |  | ||||||
|             self._user.from_dict(values["user"]) |  | ||||||
|  |  | ||||||
|         if "description" in values: |  | ||||||
|             self._description = values["description"] |  | ||||||
|  |  | ||||||
|         if "author" in values: |  | ||||||
|             from bot_graphql.filter.user_filter import UserFilter |  | ||||||
|  |  | ||||||
|             self._author: UserFilter = self._services.get_service(UserFilter) |  | ||||||
|             self._author.from_dict(values["author"]) |  | ||||||
|  |  | ||||||
|     def filter(self, query: List[UserWarnings]) -> List[UserWarnings]: |  | ||||||
|         if self._id is not None: |  | ||||||
|             query = query.where(lambda x: x.id == self._id) |  | ||||||
|  |  | ||||||
|         if self._user is not None: |  | ||||||
|             users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.id) |  | ||||||
|             query = query.where(lambda x: x.id in users) |  | ||||||
|  |  | ||||||
|         if self._description is not None: |  | ||||||
|             query = query.where(lambda x: x.description == self._description or self._description in x.description) |  | ||||||
|  |  | ||||||
|         if self._author is not None: |  | ||||||
|             users = self._author.filter(query.select(lambda x: x.author)).select(lambda x: x.id) |  | ||||||
|             query = query.where(lambda x: x.id in users) |  | ||||||
|  |  | ||||||
|         return query |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| type ServerStatistic { |  | ||||||
|     achievementsAchieved: Int |  | ||||||
|     messageCount: Int |  | ||||||
|  |  | ||||||
|     userCount: Int |  | ||||||
|     activeUserCount: Int |  | ||||||
|  |  | ||||||
|     userJoinedVoiceChannelCount: Int |  | ||||||
|     userJoinedVoiceChannelOntime: Float |  | ||||||
|  |  | ||||||
|     userJoinedGameServerCount: Int |  | ||||||
|     userJoinedGameServerOntime: Float |  | ||||||
|  |  | ||||||
|     userWarningCount: Int |  | ||||||
|  |  | ||||||
|     activityScore: Int |  | ||||||
| } |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| type UserWarning implements TableWithHistoryQuery { |  | ||||||
|     id: ID |  | ||||||
|     user: User |  | ||||||
|     description: String |  | ||||||
|     author: User |  | ||||||
|  |  | ||||||
|     createdAt: String |  | ||||||
|     modifiedAt: String |  | ||||||
|  |  | ||||||
|     history: [UserWarningHistory] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type UserWarningHistory implements HistoryTableQuery { |  | ||||||
|     id: ID |  | ||||||
|     user: ID |  | ||||||
|     description: String |  | ||||||
|     author: ID |  | ||||||
|  |  | ||||||
|     deleted: Boolean |  | ||||||
|     dateFrom: String |  | ||||||
|     dateTo: String |  | ||||||
| } |  | ||||||
|  |  | ||||||
| input UserWarningFilter { |  | ||||||
|     id: ID |  | ||||||
|     user: UserFilter |  | ||||||
| } |  | ||||||
|  |  | ||||||
| input UserWarningInput { |  | ||||||
|     id: ID |  | ||||||
|     user: ID |  | ||||||
|     description: String |  | ||||||
|     author: ID |  | ||||||
| } |  | ||||||
| @@ -1,7 +0,0 @@ | |||||||
| from bot_data.model.server import Server |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ServerStatistics: |  | ||||||
|     def __init__(self, server: Server, kwargs: dict): |  | ||||||
|         self.server = server |  | ||||||
|         self.kwargs = kwargs |  | ||||||
| @@ -1,90 +0,0 @@ | |||||||
| from datetime import datetime |  | ||||||
|  |  | ||||||
| from cpl_core.database.context import DatabaseContextABC |  | ||||||
| from cpl_discord.service import DiscordBotServiceABC |  | ||||||
|  |  | ||||||
| from bot_api.route.route import Route |  | ||||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC |  | ||||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC |  | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC |  | ||||||
| from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC |  | ||||||
| from bot_data.model.user import User |  | ||||||
| from bot_data.model.user_role_enum import UserRoleEnum |  | ||||||
| from bot_graphql.abc.query_abc import QueryABC |  | ||||||
| from modules.base.service.user_warnings_service import UserWarningsService |  | ||||||
| from modules.level.service.level_service import LevelService |  | ||||||
| from modules.permission.service.permission_service import PermissionService |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class UserMutation(QueryABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         servers: ServerRepositoryABC, |  | ||||||
|         users: UserRepositoryABC, |  | ||||||
|         bot: DiscordBotServiceABC, |  | ||||||
|         db: DatabaseContextABC, |  | ||||||
|         permissions: PermissionService, |  | ||||||
|         levels: LevelRepositoryABC, |  | ||||||
|         level_service: LevelService, |  | ||||||
|         user_warnings: UserWarningsRepositoryABC, |  | ||||||
|         user_warning_service: UserWarningsService, |  | ||||||
|     ): |  | ||||||
|         QueryABC.__init__(self, "UserMutation") |  | ||||||
|  |  | ||||||
|         self._servers = servers |  | ||||||
|         self._users = users |  | ||||||
|         self._bot = bot |  | ||||||
|         self._db = db |  | ||||||
|         self._permissions = permissions |  | ||||||
|         self._levels = levels |  | ||||||
|         self._level_service = level_service |  | ||||||
|         self._user_warnings = user_warnings |  | ||||||
|         self._user_warning_service = user_warning_service |  | ||||||
|  |  | ||||||
|         self.set_field("updateUser", self.resolve_update_user) |  | ||||||
|  |  | ||||||
|     def resolve_update_user(self, *_, input: dict): |  | ||||||
|         user = self._users.get_user_by_id(input["id"]) |  | ||||||
|  |  | ||||||
|         auth_user = Route.get_user() |  | ||||||
|         member = self._bot.get_guild(user.server.discord_id).get_member( |  | ||||||
|             auth_user.users.where(lambda x: x.server.id == user.server.id).single().discord_id |  | ||||||
|         ) |  | ||||||
|         if member.id != user.discord_id: |  | ||||||
|             self._can_user_mutate_data(user.server, UserRoleEnum.moderator) |  | ||||||
|  |  | ||||||
|             new_xp = None |  | ||||||
|             if "levelId" in input: |  | ||||||
|                 level = self._levels.get_level_by_id(input["levelId"]) |  | ||||||
|                 if user.level.id != level.id: |  | ||||||
|                     new_xp = level.min_xp |  | ||||||
|  |  | ||||||
|             if "userWarnings" in input: |  | ||||||
|                 self._update_user_warning(user, input["userWarnings"]) |  | ||||||
|  |  | ||||||
|             user.xp = new_xp if new_xp is not None else input["xp"] if "xp" in input else user.xp |  | ||||||
|  |  | ||||||
|         user.birthday = datetime.strptime(input["birthday"], "%d.%m.%Y") if "birthday" in input else user.birthday |  | ||||||
|  |  | ||||||
|         self._users.update_user(user) |  | ||||||
|         self._db.save_changes() |  | ||||||
|         self._bot.loop.create_task(self._level_service.set_level(user)) |  | ||||||
|  |  | ||||||
|         user = self._users.get_user_by_id(input["id"]) |  | ||||||
|         return user |  | ||||||
|  |  | ||||||
|     def _update_user_warning(self, user: User, new_warnings: dict): |  | ||||||
|         old_warnings = self._user_warnings.get_user_warnings_by_user_id(user.id) |  | ||||||
|         for warning in old_warnings: |  | ||||||
|             if warning.id in [int(x["id"]) if "id" in x else None for x in new_warnings]: |  | ||||||
|                 continue |  | ||||||
|  |  | ||||||
|             self._user_warning_service.remove_warnings(warning.id) |  | ||||||
|  |  | ||||||
|         for warning in new_warnings: |  | ||||||
|             if "id" in warning and int(warning["id"]) in old_warnings.select(lambda x: x.id): |  | ||||||
|                 continue |  | ||||||
|  |  | ||||||
|             member = self._bot.get_guild(user.server.discord_id).get_member(user.discord_id) |  | ||||||
|             author = self._users.get_user_by_id(int(warning["author"])) |  | ||||||
|             self._user_warning_service.add_warnings(member, warning["description"], author.discord_id) |  | ||||||
| @@ -1,157 +0,0 @@ | |||||||
| import datetime |  | ||||||
|  |  | ||||||
| from cpl_core.configuration import ConfigurationABC |  | ||||||
|  |  | ||||||
| from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC |  | ||||||
| from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC |  | ||||||
| from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC |  | ||||||
| from bot_data.abc.user_message_count_per_hour_repository_abc import UserMessageCountPerHourRepositoryABC |  | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC |  | ||||||
| from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC |  | ||||||
| from bot_data.model.server_config import ServerConfig |  | ||||||
| from bot_graphql.abc.query_abc import QueryABC |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ServerStatisticQuery(QueryABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         config: ConfigurationABC, |  | ||||||
|         users: UserRepositoryABC, |  | ||||||
|         user_joined_voice_channels: UserJoinedVoiceChannelRepositoryABC, |  | ||||||
|         user_joined_game_servers: UserJoinedGameServerRepositoryABC, |  | ||||||
|         user_messages: UserMessageCountPerHourRepositoryABC, |  | ||||||
|         user_warnings: UserWarningsRepositoryABC, |  | ||||||
|         achievements: AchievementRepositoryABC, |  | ||||||
|     ): |  | ||||||
|         QueryABC.__init__(self, "ServerStatistic") |  | ||||||
|  |  | ||||||
|         self._config = config |  | ||||||
|         self._users = users |  | ||||||
|         self._user_joined_voice_channels = user_joined_voice_channels |  | ||||||
|         self._user_joined_game_servers = user_joined_game_servers |  | ||||||
|         self._user_messages = user_messages |  | ||||||
|         self._user_warnings = user_warnings |  | ||||||
|         self._achievements = achievements |  | ||||||
|  |  | ||||||
|         self.set_field( |  | ||||||
|             "achievementsAchieved", |  | ||||||
|             self._resolve_achievements, |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self.set_field( |  | ||||||
|             "messageCount", |  | ||||||
|             self._resolve_message_count, |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         self.set_field("userCount", lambda server, *_: self._users.get_users_by_server_id(server.server.id).count()) |  | ||||||
|         self.set_field("activeUserCount", self._resolve_active_count) |  | ||||||
|  |  | ||||||
|         self.set_field("userJoinedVoiceChannelCount", self._resolve_voice_channel_count) |  | ||||||
|         self.set_field("userJoinedVoiceChannelOntime", self._resolve_voice_channel_ontime) |  | ||||||
|  |  | ||||||
|         self.set_field("userJoinedGameServerCount", self._resolve_game_server_count) |  | ||||||
|         self.set_field("userJoinedGameServerOntime", self._resolve_game_server_ontime) |  | ||||||
|  |  | ||||||
|         self.set_field("userWarningCount", self._resolve_user_warning_count) |  | ||||||
|  |  | ||||||
|         self.set_field("activityScore", self._resolve_activity_score) |  | ||||||
|  |  | ||||||
|     def _resolve_activity_score(self, server, *_): |  | ||||||
|         days = (datetime.date.today() - self._get_date(**server.kwargs)).days |  | ||||||
|         return int( |  | ||||||
|             ( |  | ||||||
|                 ( |  | ||||||
|                     self._resolve_achievements(server, *_) |  | ||||||
|                     + self._resolve_message_count(server, *_) |  | ||||||
|                     + self._resolve_voice_channel_count(server, *_) |  | ||||||
|                     + self._resolve_voice_channel_ontime(server, *_) |  | ||||||
|                     + self._resolve_game_server_count(server, *_) |  | ||||||
|                     + self._resolve_game_server_ontime(server, *_) |  | ||||||
|                     - self._resolve_user_warning_count(server, *_) |  | ||||||
|                 ) |  | ||||||
|                 / self._resolve_active_count(server, *_) |  | ||||||
|             ) |  | ||||||
|             / days |  | ||||||
|             * 1000 |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _resolve_message_count(self, server, *_): |  | ||||||
|         settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.server.discord_id}") |  | ||||||
|         return ( |  | ||||||
|             self._user_messages.get_user_message_count_per_hours() |  | ||||||
|             .where( |  | ||||||
|                 lambda x: x.user.server.id == server.server.id |  | ||||||
|                 and x.created_at.date() >= self._get_date(**server.kwargs) |  | ||||||
|             ) |  | ||||||
|             .sum(lambda x: x.xp_count / settings.xp_per_message) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _resolve_active_count(self, server, *_): |  | ||||||
|         return self._users.get_users_by_server_id(server.server.id).where(lambda x: not x.left_server).count() |  | ||||||
|  |  | ||||||
|     def _resolve_voice_channel_count(self, server, *_): |  | ||||||
|         return ( |  | ||||||
|             self._user_joined_voice_channels.get_user_joined_voice_channels() |  | ||||||
|             .where( |  | ||||||
|                 lambda x: x.user.server.id == server.server.id |  | ||||||
|                 and x.created_at.date() >= self._get_date(**server.kwargs) |  | ||||||
|             ) |  | ||||||
|             .count() |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _resolve_voice_channel_ontime(self, server, *_): |  | ||||||
|         return ( |  | ||||||
|             self._user_joined_voice_channels.get_user_joined_voice_channels() |  | ||||||
|             .where( |  | ||||||
|                 lambda x: x.user.server.id == server.server.id |  | ||||||
|                 and x.created_at.date() >= self._get_date(**server.kwargs) |  | ||||||
|             ) |  | ||||||
|             .sum(lambda x: x.time) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _resolve_game_server_count(self, server, *_): |  | ||||||
|         return ( |  | ||||||
|             self._user_joined_game_servers.get_user_joined_game_servers() |  | ||||||
|             .where( |  | ||||||
|                 lambda x: x.user.server.id == server.server.id |  | ||||||
|                 and x.created_at.date() >= self._get_date(**server.kwargs) |  | ||||||
|             ) |  | ||||||
|             .count() |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _resolve_game_server_ontime(self, server, *_): |  | ||||||
|         return ( |  | ||||||
|             self._user_joined_game_servers.get_user_joined_game_servers() |  | ||||||
|             .where( |  | ||||||
|                 lambda x: x.user.server.id == server.server.id |  | ||||||
|                 and x.created_at.date() >= self._get_date(**server.kwargs) |  | ||||||
|             ) |  | ||||||
|             .sum(lambda x: x.time) |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _resolve_user_warning_count(self, server, *_): |  | ||||||
|         return ( |  | ||||||
|             self._user_warnings.get_user_warnings() |  | ||||||
|             .where( |  | ||||||
|                 lambda x: x.user.server.id == server.server.id |  | ||||||
|                 and x.created_at.date() >= self._get_date(**server.kwargs) |  | ||||||
|             ) |  | ||||||
|             .count() |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _resolve_achievements(self, server, *_): |  | ||||||
|         return ( |  | ||||||
|             self._achievements.get_achievements_by_server_id(server.server.id) |  | ||||||
|             .select_many(lambda x: self._achievements.get_user_got_achievements_by_achievement_id(x.id)) |  | ||||||
|             .where( |  | ||||||
|                 lambda x: x.user.server.id == server.server.id |  | ||||||
|                 and x.created_at.date() >= self._get_date(**server.kwargs) |  | ||||||
|             ) |  | ||||||
|             .count() |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _get_date(self, **kwargs) -> datetime.date: |  | ||||||
|         if "date" not in kwargs: |  | ||||||
|             return datetime.date.today() - datetime.timedelta(days=7) |  | ||||||
|  |  | ||||||
|         return datetime.datetime.strptime(kwargs["date"], "%d.%m.%Y").date() |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| from bot_graphql.abc.history_query_abc import HistoryQueryABC |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class UserWarningHistoryQuery(HistoryQueryABC): |  | ||||||
|     def __init__(self): |  | ||||||
|         HistoryQueryABC.__init__(self, "UserWarning") |  | ||||||
|  |  | ||||||
|         self.set_field("id", lambda x, *_: x.id) |  | ||||||
|         self.set_field("user", lambda x, *_: x.user) |  | ||||||
|         self.set_field("description", lambda x, *_: x.description) |  | ||||||
|         self.set_field("author", lambda x, *_: x.author) |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| from cpl_core.database.context import DatabaseContextABC |  | ||||||
|  |  | ||||||
| from bot_data.model.user_warnings_history import UserWarningsHistory |  | ||||||
| from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class UserWarningQuery(DataQueryWithHistoryABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         db: DatabaseContextABC, |  | ||||||
|     ): |  | ||||||
|         DataQueryWithHistoryABC.__init__(self, "UserWarning", "UserWarningsHistory", UserWarningsHistory, db) |  | ||||||
|  |  | ||||||
|         self.set_field("id", lambda x, *_: x.id) |  | ||||||
|         self.set_field("user", lambda x, *_: x.user) |  | ||||||
|         self.set_field("description", lambda x, *_: x.description) |  | ||||||
|         self.set_field("author", lambda x, *_: x.author) |  | ||||||
| @@ -1,68 +0,0 @@ | |||||||
| import datetime |  | ||||||
|  |  | ||||||
| from cpl_core.configuration import ConfigurationABC |  | ||||||
| from cpl_core.database.context import DatabaseContextABC |  | ||||||
| from cpl_discord.service import DiscordBotServiceABC |  | ||||||
| from cpl_translation import TranslatePipe |  | ||||||
| from discord.ext import tasks |  | ||||||
|  |  | ||||||
| from bot_core.abc.task_abc import TaskABC |  | ||||||
| from bot_core.logging.task_logger import TaskLogger |  | ||||||
| from bot_core.service.message_service import MessageService |  | ||||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC |  | ||||||
| from bot_data.model.server_config import ServerConfig |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class BirthdayWatcher(TaskABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         config: ConfigurationABC, |  | ||||||
|         logger: TaskLogger, |  | ||||||
|         bot: DiscordBotServiceABC, |  | ||||||
|         db: DatabaseContextABC, |  | ||||||
|         users: UserRepositoryABC, |  | ||||||
|         message_service: MessageService, |  | ||||||
|         t: TranslatePipe, |  | ||||||
|     ): |  | ||||||
|         TaskABC.__init__(self) |  | ||||||
|  |  | ||||||
|         self._config = config |  | ||||||
|         self._logger = logger |  | ||||||
|         self._bot = bot |  | ||||||
|         self._db = db |  | ||||||
|         self._users = users |  | ||||||
|         self._message_service = message_service |  | ||||||
|         self._t = t |  | ||||||
|  |  | ||||||
|         if not self._is_maintenance(): |  | ||||||
|             self.watch.start() |  | ||||||
|  |  | ||||||
|     @tasks.loop(time=datetime.time(hour=8, minute=0)) |  | ||||||
|     async def watch(self): |  | ||||||
|         self._logger.info(__name__, "Watching birthdays") |  | ||||||
|         try: |  | ||||||
|             today = datetime.date.today() |  | ||||||
|             users = self._users.get_users().where(lambda x: x.birthday is not None) |  | ||||||
|             for user in users: |  | ||||||
|                 if user.birthday.day != today.day or user.birthday.month != today.month: |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|                 settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{user.server.discord_id}") |  | ||||||
|  |  | ||||||
|                 user.xp += settings.xp_for_birthday |  | ||||||
|                 self._users.update_user(user) |  | ||||||
|                 self._db.save_changes() |  | ||||||
|  |  | ||||||
|                 guild = self._bot.get_guild(user.server.discord_id) |  | ||||||
|                 member = guild.get_member(user.discord_id) |  | ||||||
|                 await self._message_service.send_channel_message( |  | ||||||
|                     self._bot.get_channel(settings.notification_chat_id), |  | ||||||
|                     self._t.transform("modules.base.user.birthday.has_birthday").format(member.mention), |  | ||||||
|                     is_persistent=True, |  | ||||||
|                 ) |  | ||||||
|         except Exception as e: |  | ||||||
|             self._logger.error(__name__, f"Watching birthdays failed", e) |  | ||||||
|  |  | ||||||
|     @watch.before_loop |  | ||||||
|     async def wait(self): |  | ||||||
|         await self._wait_until_ready() |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| { |  | ||||||
|   "DefaultLevel": { |  | ||||||
|     "LevelHeader": "~~~ dev-Level ~~~", |  | ||||||
|     "Levels": [ |  | ||||||
|       { |  | ||||||
|         "Name": "dev-Newbie", |  | ||||||
|         "Color": "0x1abc9c", |  | ||||||
|         "MinXp": 0, |  | ||||||
|         "Permissions": 968552209984 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "dev-Keks", |  | ||||||
|         "Color": "0x2ecc71", |  | ||||||
|         "MinXp": 100, |  | ||||||
|         "Permissions": 1002928856640 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "dev-Doppelkeks", |  | ||||||
|         "Color": "0x3498db", |  | ||||||
|         "MinXp": 200, |  | ||||||
|         "Permissions": 1071849660224 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "dev-Auror", |  | ||||||
|         "Color": "0xf1c40f", |  | ||||||
|         "MinXp": 300, |  | ||||||
|         "Permissions": 1089042120513 |  | ||||||
|       } |  | ||||||
|     ] |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| { |  | ||||||
|   "DefaultLevel": { |  | ||||||
|     "LevelHeader": "~~~ ed-Level ~~~", |  | ||||||
|     "Levels": [ |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Newbie", |  | ||||||
|         "Color": "0x1abc9c", |  | ||||||
|         "MinXp": 0, |  | ||||||
|         "Permissions": 968552209984 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Keks", |  | ||||||
|         "Color": "0x2ecc71", |  | ||||||
|         "MinXp": 100, |  | ||||||
|         "Permissions": 1002928856640 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Doppelkeks", |  | ||||||
|         "Color": "0x3498db", |  | ||||||
|         "MinXp": 200, |  | ||||||
|         "Permissions": 1071849660224 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Auror", |  | ||||||
|         "Color": "0xf1c40f", |  | ||||||
|         "MinXp": 300, |  | ||||||
|         "Permissions": 1089042120513 |  | ||||||
|       } |  | ||||||
|     ] |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| { |  | ||||||
|   "DefaultLevel": { |  | ||||||
|     "LevelHeader": "~~~ ed-Level ~~~", |  | ||||||
|     "Levels": [ |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Newbie", |  | ||||||
|         "Color": "0x1abc9c", |  | ||||||
|         "MinXp": 0, |  | ||||||
|         "Permissions": 968552209984 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Keks", |  | ||||||
|         "Color": "0x2ecc71", |  | ||||||
|         "MinXp": 100, |  | ||||||
|         "Permissions": 1002928856640 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Doppelkeks", |  | ||||||
|         "Color": "0x3498db", |  | ||||||
|         "MinXp": 200, |  | ||||||
|         "Permissions": 1071849660224 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "ed-Auror", |  | ||||||
|         "Color": "0xf1c40f", |  | ||||||
|         "MinXp": 300, |  | ||||||
|         "Permissions": 1089042120513 |  | ||||||
|       } |  | ||||||
|     ] |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| { |  | ||||||
|   "DefaultLevel": { |  | ||||||
|     "LevelHeader": "~~~ test-Level ~~~", |  | ||||||
|     "Levels": [ |  | ||||||
|       { |  | ||||||
|         "Name": "test-Newbie", |  | ||||||
|         "Color": "0x1abc9c", |  | ||||||
|         "MinXp": 0, |  | ||||||
|         "Permissions": 968552209984 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "test-Keks", |  | ||||||
|         "Color": "0x2ecc71", |  | ||||||
|         "MinXp": 100, |  | ||||||
|         "Permissions": 1002928856640 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "test-Doppelkeks", |  | ||||||
|         "Color": "0x3498db", |  | ||||||
|         "MinXp": 200, |  | ||||||
|         "Permissions": 1071849660224 |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         "Name": "test-Auror", |  | ||||||
|         "Color": "0xf1c40f", |  | ||||||
|         "MinXp": 300, |  | ||||||
|         "Permissions": 1089042120513 |  | ||||||
|       } |  | ||||||
|     ] |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,74 +0,0 @@ | |||||||
| 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 modules.permission.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 |  | ||||||
|  |  | ||||||
|     def _has_member_role(self, member: discord.Member, team_member_type: TeamMemberTypeEnum) -> bool: |  | ||||||
|         if member is None or member.guild is None: |  | ||||||
|             return False |  | ||||||
|  |  | ||||||
|         self._logger.debug(__name__, f"Checking is member {member.name} {team_member_type.value}") |  | ||||||
|  |  | ||||||
|         try: |  | ||||||
|             server = self._servers.get_server_by_discord_id(member.guild.id) |  | ||||||
|             config = self._server_configs.get_server_config_by_server(server.id) |  | ||||||
|             roles = config.team_role_ids.where(lambda x: x.team_member_type == team_member_type).select( |  | ||||||
|                 lambda x: member.guild.get_role(x.role_id) |  | ||||||
|             ) |  | ||||||
|             for role in roles: |  | ||||||
|                 if role not in member.roles: |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|                 return True |  | ||||||
|         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 |  | ||||||
|  |  | ||||||
|         self._logger.debug(__name__, f"Checking is member {member.name} technician") |  | ||||||
|  |  | ||||||
|         try: |  | ||||||
|             tech_config = self._technician_configs.get_technician_config() |  | ||||||
|             if member.id in tech_config.technician_ids: |  | ||||||
|                 return True |  | ||||||
|         except Exception as e: |  | ||||||
|             self._logger.error(__name__, "Permission check failed", e) |  | ||||||
|  |  | ||||||
|         return False |  | ||||||
| @@ -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__ = "modules.special_offers" |  | ||||||
| __author__ = "Sven Heidemann" |  | ||||||
| __license__ = "MIT" |  | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" |  | ||||||
| __version__ = "1.2.0" |  | ||||||
|  |  | ||||||
| from collections import namedtuple |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # imports |  | ||||||
|  |  | ||||||
| VersionInfo = namedtuple("VersionInfo", "major minor micro") |  | ||||||
| version_info = VersionInfo(major="1", minor="2", micro="0") |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| { |  | ||||||
|   "ProjectSettings": { |  | ||||||
|     "Name": "steam-special-offers", |  | ||||||
|     "Version": { |  | ||||||
|       "Major": "1", |  | ||||||
|       "Minor": "2", |  | ||||||
|       "Micro": "0" |  | ||||||
|     }, |  | ||||||
|     "Author": "", |  | ||||||
|     "AuthorEmail": "", |  | ||||||
|     "Description": "", |  | ||||||
|     "LongDescription": "", |  | ||||||
|     "URL": "", |  | ||||||
|     "CopyrightDate": "", |  | ||||||
|     "CopyrightName": "", |  | ||||||
|     "LicenseName": "", |  | ||||||
|     "LicenseDescription": "", |  | ||||||
|     "Dependencies": [ |  | ||||||
|       "cpl-core>=1.2.0" |  | ||||||
|     ], |  | ||||||
|     "DevDependencies": [ |  | ||||||
|       "cpl-cli>=1.2.0" |  | ||||||
|     ], |  | ||||||
|     "PythonVersion": ">=3.10.4", |  | ||||||
|     "PythonPath": { |  | ||||||
|       "linux": "" |  | ||||||
|     }, |  | ||||||
|     "Classifiers": [] |  | ||||||
|   }, |  | ||||||
|   "BuildSettings": { |  | ||||||
|     "ProjectType": "library", |  | ||||||
|     "SourcePath": "", |  | ||||||
|     "OutputPath": "../../dist", |  | ||||||
|     "Main": "steam_special_offers.main", |  | ||||||
|     "EntryPoint": "steam-special-offers", |  | ||||||
|     "IncludePackageData": false, |  | ||||||
|     "Included": [], |  | ||||||
|     "Excluded": [ |  | ||||||
|       "*/__pycache__", |  | ||||||
|       "*/logs", |  | ||||||
|       "*/tests" |  | ||||||
|     ], |  | ||||||
|     "PackageData": {}, |  | ||||||
|     "ProjectReferences": [] |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,22 +0,0 @@ | |||||||
| from cpl_core.configuration import ConfigurationABC |  | ||||||
| from cpl_core.dependency_injection import ServiceCollectionABC |  | ||||||
| from cpl_core.environment import ApplicationEnvironmentABC |  | ||||||
| from cpl_discord.service.discord_collection_abc import DiscordCollectionABC |  | ||||||
|  |  | ||||||
| from bot_core.abc.module_abc import ModuleABC |  | ||||||
| from bot_core.abc.task_abc import TaskABC |  | ||||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum |  | ||||||
| from modules.special_offers.steam_offer_watcher import SteamOfferWatcher |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SteamSpecialOffersModule(ModuleABC): |  | ||||||
|     def __init__(self, dc: DiscordCollectionABC): |  | ||||||
|         ModuleABC.__init__(self, dc, FeatureFlagsEnum.steam_special_offers_module) |  | ||||||
|  |  | ||||||
|     def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): |  | ||||||
|         services.add_singleton(TaskABC, SteamOfferWatcher) |  | ||||||
|         # commands |  | ||||||
|         # events |  | ||||||
| @@ -1,220 +0,0 @@ | |||||||
| import asyncio |  | ||||||
| import datetime |  | ||||||
|  |  | ||||||
| import bs4 |  | ||||||
| import discord |  | ||||||
| import requests |  | ||||||
| from cpl_core.configuration import ConfigurationABC |  | ||||||
| from cpl_core.database.context import DatabaseContextABC |  | ||||||
| from cpl_discord.service import DiscordBotServiceABC |  | ||||||
| from cpl_query.extension import List |  | ||||||
| from cpl_translation import TranslatePipe |  | ||||||
| from discord.ext import tasks |  | ||||||
|  |  | ||||||
| from bot_core.abc.task_abc import TaskABC |  | ||||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum |  | ||||||
| from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings |  | ||||||
| from bot_core.logging.task_logger import TaskLogger |  | ||||||
| from bot_core.service.message_service import MessageService |  | ||||||
| from bot_data.abc.steam_special_offer_repository_abc import ( |  | ||||||
|     SteamSpecialOfferRepositoryABC, |  | ||||||
| ) |  | ||||||
| from bot_data.model.server_config import ServerConfig |  | ||||||
| from bot_data.model.steam_special_offer import SteamSpecialOffer |  | ||||||
| from bot_data.model.technician_config import TechnicianConfig |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SteamOfferWatcher(TaskABC): |  | ||||||
|     def __init__( |  | ||||||
|         self, |  | ||||||
|         config: ConfigurationABC, |  | ||||||
|         bot: DiscordBotServiceABC, |  | ||||||
|         logger: TaskLogger, |  | ||||||
|         db: DatabaseContextABC, |  | ||||||
|         offers: SteamSpecialOfferRepositoryABC, |  | ||||||
|         message_service: MessageService, |  | ||||||
|         t: TranslatePipe, |  | ||||||
|         tech_config: TechnicianConfig, |  | ||||||
|     ): |  | ||||||
|         TaskABC.__init__(self) |  | ||||||
|  |  | ||||||
|         self._config = config |  | ||||||
|         self._logger = logger |  | ||||||
|         self._db = db |  | ||||||
|         self._offers = offers |  | ||||||
|         self._bot = bot |  | ||||||
|         self._message_service = message_service |  | ||||||
|         self._t = t |  | ||||||
|         self._tech_config = tech_config |  | ||||||
|  |  | ||||||
|         self._is_new = False |  | ||||||
|         self._urls = {} |  | ||||||
|         self._image_urls = {} |  | ||||||
|  |  | ||||||
|         if not self._is_maintenance(): |  | ||||||
|             self.watch.start() |  | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def _get_max_count() -> int: |  | ||||||
|         count = 0 |  | ||||||
|         result = requests.get(f"https://store.steampowered.com/search/results?specials=1") |  | ||||||
|         soup = bs4.BeautifulSoup(result.text, "lxml") |  | ||||||
|         element = soup.find_all("div", {"class": "search_results_count"}) |  | ||||||
|         if len(element) < 1: |  | ||||||
|             return count |  | ||||||
|  |  | ||||||
|         count = int(element[0].contents[0].split(" ")[0].replace(",", "")) |  | ||||||
|  |  | ||||||
|         return count |  | ||||||
|  |  | ||||||
|     def _get_games_from_page(self, start: int, count: int) -> List[SteamSpecialOffer]: |  | ||||||
|         games = List(SteamSpecialOffer) |  | ||||||
|         result = requests.get( |  | ||||||
|             f"https://store.steampowered.com/search/results?query&start={start}&count={count}&force_infinite=1&specials=1&filter=topsellers" |  | ||||||
|         ) |  | ||||||
|         soup = bs4.BeautifulSoup(result.text, "lxml") |  | ||||||
|         elements = soup.find_all("a", {"class": "search_result_row"}) |  | ||||||
|         if len(elements) < 1: |  | ||||||
|             return games |  | ||||||
|  |  | ||||||
|         for element in elements: |  | ||||||
|             name_element = element.find("span", {"class": "title"}) |  | ||||||
|             original_price_element = element.find("div", {"class": "discount_original_price"}) |  | ||||||
|             discount_element = element.find("div", {"class": "discount_pct"}) |  | ||||||
|             discount_price_element = element.find("div", {"class": "discount_final_price"}) |  | ||||||
|  |  | ||||||
|             if ( |  | ||||||
|                 name_element is None |  | ||||||
|                 or len(name_element.contents) < 1 |  | ||||||
|                 or original_price_element is None |  | ||||||
|                 or len(original_price_element.contents) < 1 |  | ||||||
|                 or discount_element is None |  | ||||||
|                 or len(discount_element.contents) < 1 |  | ||||||
|                 or discount_price_element is None |  | ||||||
|                 or len(discount_price_element.contents) < 1 |  | ||||||
|             ): |  | ||||||
|                 continue |  | ||||||
|  |  | ||||||
|             name = name_element.contents[0].replace("'", "`").replace('"', "`") |  | ||||||
|             original_price = float( |  | ||||||
|                 original_price_element.contents[0].replace(" ", "").replace("€", "").replace(",", ".") |  | ||||||
|             ) |  | ||||||
|             discount = int(discount_element.contents[0].replace("%", "")) |  | ||||||
|             discount_price = float( |  | ||||||
|                 discount_price_element.contents[0].replace(" ", "").replace("€", "").replace(",", ".") |  | ||||||
|             ) |  | ||||||
|             games.add(SteamSpecialOffer(name, original_price, discount_price, discount)) |  | ||||||
|             self._urls[name] = element.attrs["href"] |  | ||||||
|             self._image_urls[name] = element.find("div", {"class": "search_capsule"}).find("img").attrs["src"] |  | ||||||
|  |  | ||||||
|         return games |  | ||||||
|  |  | ||||||
|     def _get_new_game_offers(self) -> List[SteamSpecialOffer]: |  | ||||||
|         new_offers = List(SteamSpecialOffer) |  | ||||||
|  |  | ||||||
|         sale_count = self._tech_config.max_steam_offer_count |  | ||||||
|         # todo: let admins change the value |  | ||||||
|         self._logger.debug(__name__, f"Get special offers from 0 to {sale_count}") |  | ||||||
|         for i in range(0, sale_count, 100): |  | ||||||
|             if i > sale_count: |  | ||||||
|                 break |  | ||||||
|             new_offers.extend(self._get_games_from_page(i, 100)) |  | ||||||
|  |  | ||||||
|         self._logger.debug(__name__, f"Got {new_offers.count()} offers") |  | ||||||
|  |  | ||||||
|         return new_offers |  | ||||||
|  |  | ||||||
|     async def _send_embed_for_offer(self, offer: SteamSpecialOffer, channel_id: int) -> discord.Embed: |  | ||||||
|         embed = discord.Embed( |  | ||||||
|             title=offer.name, |  | ||||||
|             url=self._urls[offer.name], |  | ||||||
|             color=int("ef9d0d", 16), |  | ||||||
|             timestamp=datetime.datetime.now(), |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         embed.add_field( |  | ||||||
|             name=self._t.transform("modules.special_offers.price"), |  | ||||||
|             value=f"~~{offer.original_price}€~~", |  | ||||||
|             inline=True, |  | ||||||
|         ) |  | ||||||
|         embed.add_field( |  | ||||||
|             name=self._t.transform("modules.special_offers.discount"), |  | ||||||
|             value=f"{offer.discount_pct}%", |  | ||||||
|             inline=True, |  | ||||||
|         ) |  | ||||||
|         embed.add_field( |  | ||||||
|             name=self._t.transform("modules.special_offers.discount_price"), |  | ||||||
|             value=f"{offer.discount_price}€", |  | ||||||
|             inline=True, |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         embed.set_image(url=self._image_urls[offer.name]) |  | ||||||
|  |  | ||||||
|         await self._message_service.send_channel_message( |  | ||||||
|             self._bot.get_channel(channel_id), |  | ||||||
|             embed, |  | ||||||
|             is_persistent=True, |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     def _watch(self) -> List[SteamSpecialOffer]: |  | ||||||
|         self._is_new = self._offers.get_steam_special_offers().count() == 0 |  | ||||||
|         new_offers = self._get_new_game_offers() |  | ||||||
|         new_offers_names = new_offers.select(lambda x: x.name).to_list() |  | ||||||
|  |  | ||||||
|         old_offers = self._offers.get_steam_special_offers() |  | ||||||
|         old_offers_names = old_offers.select(lambda x: x.name).to_list() |  | ||||||
|  |  | ||||||
|         offers_for_notifications = List(SteamSpecialOffer) |  | ||||||
|  |  | ||||||
|         for offer in old_offers: |  | ||||||
|             offer: SteamSpecialOffer = offer |  | ||||||
|             if offer.name in new_offers_names: |  | ||||||
|                 continue |  | ||||||
|  |  | ||||||
|             self._offers.delete_steam_special_offer(offer) |  | ||||||
|             self._db.save_changes() |  | ||||||
|  |  | ||||||
|         for offer in new_offers: |  | ||||||
|             if offer.name in old_offers_names: |  | ||||||
|                 self._offers.update_steam_special_offer(offer) |  | ||||||
|                 self._db.save_changes() |  | ||||||
|                 continue |  | ||||||
|  |  | ||||||
|             self._offers.add_steam_special_offer(offer) |  | ||||||
|             self._db.save_changes() |  | ||||||
|             offers_for_notifications.add(offer) |  | ||||||
|  |  | ||||||
|         self._logger.trace(__name__, "Finished watching") |  | ||||||
|         return offers_for_notifications |  | ||||||
|  |  | ||||||
|     @tasks.loop(hours=4) |  | ||||||
|     async def watch(self): |  | ||||||
|         self._logger.info(__name__, "Watching steam special offers") |  | ||||||
|         try: |  | ||||||
|             offers_for_notifications = self._watch() |  | ||||||
|             self._logger.debug( |  | ||||||
|                 __name__, |  | ||||||
|                 f"Sending offer notifications for {offers_for_notifications.count()} offers", |  | ||||||
|             ) |  | ||||||
|             if self._is_new: |  | ||||||
|                 return |  | ||||||
|             for guild in self._bot.guilds: |  | ||||||
|                 settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}") |  | ||||||
|                 if ( |  | ||||||
|                     not FeatureFlagsSettings.get_flag_from_dict( |  | ||||||
|                         settings.feature_flags, FeatureFlagsEnum.steam_special_offers |  | ||||||
|                     ) |  | ||||||
|                     or settings.game_offer_notification_chat_id is None |  | ||||||
|                 ): |  | ||||||
|                     continue |  | ||||||
|  |  | ||||||
|                 for offer in offers_for_notifications: |  | ||||||
|                     self._bot.loop.create_task( |  | ||||||
|                         self._send_embed_for_offer(offer, settings.game_offer_notification_chat_id) |  | ||||||
|                     ) |  | ||||||
|         except Exception as e: |  | ||||||
|             self._logger.error(__name__, f"Steam offer watcher failed", e) |  | ||||||
|  |  | ||||||
|     @watch.before_loop |  | ||||||
|     async def wait(self): |  | ||||||
|         await self._wait_until_ready() |  | ||||||
| @@ -5,7 +5,7 @@ volumes: | |||||||
|  |  | ||||||
| services: | services: | ||||||
|   kdb_bot_staging_1: |   kdb_bot_staging_1: | ||||||
|     image: sh-edraft.de/kdb-bot:1.1.10 |     image: sh-edraft.de/kdb-bot:1.1.9 | ||||||
|     restart: unless-stopped |     restart: unless-stopped | ||||||
|     depends_on: |     depends_on: | ||||||
|       - kdb_db_staging_1 |       - kdb_db_staging_1 | ||||||
| @@ -32,7 +32,7 @@ services: | |||||||
|           memory: 1024M |           memory: 1024M | ||||||
|  |  | ||||||
|   kdb_web_staging_1: |   kdb_web_staging_1: | ||||||
|     image: sh-edraft.de/kdb-web:1.1.10 |     image: sh-edraft.de/kdb-web:1.1.9 | ||||||
|     depends_on: |     depends_on: | ||||||
|       - kdb_bot_staging_1 |       - kdb_bot_staging_1 | ||||||
|     networks: |     networks: | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ volumes: | |||||||
|  |  | ||||||
| services: | services: | ||||||
|   kdb_bot_prod_1: |   kdb_bot_prod_1: | ||||||
|     image: sh-edraft.de/kdb-bot:1.1.10 |     image: sh-edraft.de/kdb-bot:1.1.9 | ||||||
|     restart: unless-stopped |     restart: unless-stopped | ||||||
|     depends_on: |     depends_on: | ||||||
|       - kdb_db_prod_1 |       - kdb_db_prod_1 | ||||||
| @@ -31,7 +31,7 @@ services: | |||||||
|           memory: 1024M |           memory: 1024M | ||||||
|  |  | ||||||
|   kdb_web_prod_1: |   kdb_web_prod_1: | ||||||
|     image: sh-edraft.de/kdb-web:1.1.10 |     image: sh-edraft.de/kdb-web:1.1.9 | ||||||
|     depends_on: |     depends_on: | ||||||
|       - kdb_bot_prod_1 |       - kdb_bot_prod_1 | ||||||
|     networks: |     networks: | ||||||
|   | |||||||
| @@ -17,7 +17,6 @@ | |||||||
|       "permission": "src/modules/permission/permission.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", |  | ||||||
|       "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", | ||||||
| @@ -32,12 +31,12 @@ | |||||||
|       "pre-build": "cpl set-version $ARGS; black ./;", |       "pre-build": "cpl set-version $ARGS; black ./;", | ||||||
|       "post-build": "cpl run post-build --dev; black ./;", |       "post-build": "cpl run post-build --dev; black ./;", | ||||||
|       "pre-prod": "cpl build", |       "pre-prod": "cpl build", | ||||||
|       "prod": "export SDB_ENVIRONMENT=production; export SDB_NAME=SDB-Prod; cpl start;", |       "prod": "export KDB_ENVIRONMENT=production; export KDB_NAME=KDB-Prod; cpl start;", | ||||||
|       "pre-stage": "cpl build", |       "pre-stage": "cpl build", | ||||||
|       "stage": "export SDB_ENVIRONMENT=staging; export SDB_NAME=SDB-Stage; cpl start;", |       "stage": "export KDB_ENVIRONMENT=staging; export KDB_NAME=KDB-Stage; cpl start;", | ||||||
|       "pre-dev": "cpl build", |       "pre-dev": "cpl build", | ||||||
|       "dev": "export SDB_ENVIRONMENT=development; export SDB_NAME=SDB-Dev; cpl start;", |       "dev": "export KDB_ENVIRONMENT=development; export KDB_NAME=KDB-Dev; cpl start;", | ||||||
|       "docker-build": "cpl build $ARGS; docker build -t sh-edraft.de/sdb-bot:$(cpl gv) .;", |       "docker-build": "cpl build $ARGS; docker build -t sh-edraft.de/kdb-bot:$(cpl gv) .;", | ||||||
|       "dc-up": "docker-compose up -d", |       "dc-up": "docker-compose up -d", | ||||||
|       "dc-down": "docker-compose down", |       "dc-down": "docker-compose down", | ||||||
|       "docker": "cpl dc-down; cpl docker-build; cpl dc-up;" |       "docker": "cpl dc-down; cpl docker-build; cpl dc-up;" | ||||||
							
								
								
									
										1
									
								
								kdb-bot/docker
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								kdb-bot/docker
									
									
									
									
									
										Submodule
									
								
							 Submodule kdb-bot/docker added at 7ae4783874
									
								
							| @@ -2,7 +2,7 @@ | |||||||
| FROM python:3.10.4-alpine | FROM python:3.10.4-alpine | ||||||
| 
 | 
 | ||||||
| WORKDIR /app | WORKDIR /app | ||||||
| COPY ./dist/bot/build/bot/ . | COPY ./dist/bot/build/kdb-bot/ . | ||||||
| COPY ./dist/bot/build/requirements.txt . | COPY ./dist/bot/build/requirements.txt . | ||||||
| 
 | 
 | ||||||
| RUN python -m pip install --upgrade pip | RUN python -m pip install --upgrade pip | ||||||
| @@ -15,7 +15,7 @@ __title__ = "bot" | |||||||
| __author__ = "Sven Heidemann" | __author__ = "Sven Heidemann" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | __copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de" | ||||||
| __version__ = "1.2.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -8,10 +8,8 @@ from cpl_discord.service import DiscordBotServiceABC, DiscordBotService | |||||||
| from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings | from cpl_translation import TranslatePipe, TranslationServiceABC, TranslationSettings | ||||||
| 
 | 
 | ||||||
| from bot_api.api_thread import ApiThread | from bot_api.api_thread import ApiThread | ||||||
| from bot_core.abc.task_abc import TaskABC |  | ||||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||||
| from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings | ||||||
| from bot_core.environment_variables import MAINTENANCE |  | ||||||
| from bot_core.service.data_integrity_service import DataIntegrityService | from bot_core.service.data_integrity_service import DataIntegrityService | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -31,8 +29,6 @@ class Application(DiscordBotApplicationABC): | |||||||
|         # cpl-translation |         # cpl-translation | ||||||
|         self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC) |         self._translation: TranslationServiceABC = services.get_service(TranslationServiceABC) | ||||||
|         self._t: TranslatePipe = services.get_service(TranslatePipe) |         self._t: TranslatePipe = services.get_service(TranslatePipe) | ||||||
|         # internal stuff |  | ||||||
|         self._tasks = services.get_services(TaskABC) |  | ||||||
| 
 | 
 | ||||||
|         self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings) |         self._feature_flags: FeatureFlagsSettings = config.get_configuration(FeatureFlagsSettings) | ||||||
| 
 | 
 | ||||||
| @@ -59,10 +55,6 @@ class Application(DiscordBotApplicationABC): | |||||||
|                 return |                 return | ||||||
| 
 | 
 | ||||||
|             self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}") |             self._logger.info(__name__, f"Try to start {DiscordBotService.__name__}") | ||||||
|             if not self._config.get_configuration(MAINTENANCE): |  | ||||||
|                 for task in self._tasks: |  | ||||||
|                     await self._bot.add_cog(task) |  | ||||||
| 
 |  | ||||||
|             await self._bot.start_async() |             await self._bot.start_async() | ||||||
|             await self._bot.stop_async() |             await self._bot.stop_async() | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
| @@ -3,8 +3,8 @@ | |||||||
|     "Name": "bot", |     "Name": "bot", | ||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "2", |       "Minor": "1", | ||||||
|       "Micro": "0" |       "Micro": "9" | ||||||
|     }, |     }, | ||||||
|     "Author": "Sven Heidemann", |     "Author": "Sven Heidemann", | ||||||
|     "AuthorEmail": "sven.heidemann@sh-edraft.de", |     "AuthorEmail": "sven.heidemann@sh-edraft.de", | ||||||
| @@ -16,24 +16,22 @@ | |||||||
|     "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-core==2023.4.0.post5", | ||||||
|       "cpl-translation==2023.4.0.post1", |       "cpl-translation==2023.4.0.post1", | ||||||
|       "cpl-query==2023.10.0", |       "cpl-query==2023.4.0.post1", | ||||||
|       "cpl-discord==2023.10.0.post1", |       "cpl-discord==2023.4.0.post3", | ||||||
|       "Flask==3.0.0", |       "Flask==2.3.2", | ||||||
|       "Flask-Classful==0.16.0", |       "Flask-Classful==0.14.2", | ||||||
|       "Flask-Cors==4.0.0", |       "Flask-Cors==4.0.0", | ||||||
|       "PyJWT==2.8.0", |       "PyJWT==2.8.0", | ||||||
|       "waitress==2.1.2", |       "waitress==2.1.2", | ||||||
|       "Flask-SocketIO==5.3.6", |       "Flask-SocketIO==5.3.4", | ||||||
|       "eventlet==0.33.3", |       "eventlet==0.33.3", | ||||||
|       "requests-oauthlib==1.3.1", |       "requests-oauthlib==1.3.1", | ||||||
|       "icmplib==3.0.4", |       "icmplib==3.0.3", | ||||||
|       "ariadne==0.20.1", |       "ariadne==0.20.1", | ||||||
|       "cryptography==41.0.4", |       "cryptography==41.0.2", | ||||||
|       "discord==2.3.2", |       "discord>=2.3.2" | ||||||
|       "bs4==0.0.1", |  | ||||||
|       "lxml==4.9.3" |  | ||||||
|     ], |     ], | ||||||
|     "DevDependencies": [ |     "DevDependencies": [ | ||||||
|       "cpl-cli==2023.4.0.post3", |       "cpl-cli==2023.4.0.post3", | ||||||
| @@ -71,7 +69,6 @@ | |||||||
|       "../modules/level/level.json", |       "../modules/level/level.json", | ||||||
|       "../modules/permission/permission.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/technician/technician.json" |       "../modules/technician/technician.json" | ||||||
|     ] |     ] | ||||||
|   } |   } | ||||||
							
								
								
									
										1
									
								
								kdb-bot/src/bot/config
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								kdb-bot/src/bot/config
									
									
									
									
									
										Submodule
									
								
							 Submodule kdb-bot/src/bot/config added at 23eafb2e21
									
								
							| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -9,7 +9,7 @@ from bot.application import Application | |||||||
| from bot.extension.init_bot_extension import InitBotExtension | from bot.extension.init_bot_extension import InitBotExtension | ||||||
| from bot.startup import Startup | from bot.startup import Startup | ||||||
| from bot.startup_discord_extension import StartupDiscordExtension | from bot.startup_discord_extension import StartupDiscordExtension | ||||||
| from bot_data.startup_migration_extension import StartupMigrationExtension | from bot.startup_migration_extension import StartupMigrationExtension | ||||||
| from bot.startup_module_extension import StartupModuleExtension | from bot.startup_module_extension import StartupModuleExtension | ||||||
| from bot.startup_settings_extension import StartupSettingsExtension | from bot.startup_settings_extension import StartupSettingsExtension | ||||||
| from bot_api.app_api_extension import AppApiExtension | from bot_api.app_api_extension import AppApiExtension | ||||||
| @@ -14,7 +14,6 @@ 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.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.technician.technician_module import TechnicianModule | from modules.technician.technician_module import TechnicianModule | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -38,7 +37,6 @@ class ModuleList: | |||||||
|                 TechnicianModule, |                 TechnicianModule, | ||||||
|                 AchievementsModule, |                 AchievementsModule, | ||||||
|                 ShortRoleNameModule, |                 ShortRoleNameModule, | ||||||
|                 SteamSpecialOffersModule, |  | ||||||
|                 # has to be last! |                 # has to be last! | ||||||
|                 BootLogModule, |                 BootLogModule, | ||||||
|                 CoreExtensionModule, |                 CoreExtensionModule, | ||||||
| @@ -16,7 +16,6 @@ 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.message_logger import MessageLogger | from bot_core.logging.message_logger import MessageLogger | ||||||
| from bot_core.logging.task_logger import TaskLogger |  | ||||||
| from bot_data.db_context import DBContext | from bot_data.db_context import DBContext | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -44,7 +43,6 @@ class Startup(StartupABC): | |||||||
|             services.add_singleton(CustomFileLoggerABC, CommandLogger) |             services.add_singleton(CustomFileLoggerABC, CommandLogger) | ||||||
|             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) |  | ||||||
| 
 | 
 | ||||||
|         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) | ||||||
| @@ -9,29 +9,18 @@ from bot_data.migration.api_key_migration import ApiKeyMigration | |||||||
| from bot_data.migration.api_migration import ApiMigration | from bot_data.migration.api_migration import ApiMigration | ||||||
| from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration | from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration | ||||||
| from bot_data.migration.auto_role_migration import AutoRoleMigration | from bot_data.migration.auto_role_migration import AutoRoleMigration | ||||||
| from bot_data.migration.birthday_migration import BirthdayMigration | from bot_data.migration.config_feature_flags_migration import ConfigFeatureFlagsMigration | ||||||
| from bot_data.migration.config_feature_flags_migration import ( |  | ||||||
|     ConfigFeatureFlagsMigration, |  | ||||||
| ) |  | ||||||
| from bot_data.migration.config_migration import ConfigMigration | from bot_data.migration.config_migration import ConfigMigration | ||||||
| from bot_data.migration.db_history_migration import DBHistoryMigration | from bot_data.migration.db_history_migration import DBHistoryMigration | ||||||
| from bot_data.migration.default_role_migration import DefaultRoleMigration | from bot_data.migration.default_role_migration import DefaultRoleMigration | ||||||
| from bot_data.migration.fix_updates_migration import FixUpdatesMigration | from bot_data.migration.fix_updates_migration import FixUpdatesMigration | ||||||
| from bot_data.migration.fix_user_history_migration import FixUserHistoryMigration |  | ||||||
| from bot_data.migration.initial_migration import InitialMigration | from bot_data.migration.initial_migration import InitialMigration | ||||||
| from bot_data.migration.level_migration import LevelMigration | from bot_data.migration.level_migration import LevelMigration | ||||||
| from bot_data.migration.maintenance_mode_migration import MaintenanceModeMigration |  | ||||||
| from bot_data.migration.max_steam_offer_count_migration import MaxSteamOfferCountMigration |  | ||||||
| from bot_data.migration.remove_stats_migration import RemoveStatsMigration | from bot_data.migration.remove_stats_migration import RemoveStatsMigration | ||||||
| from bot_data.migration.short_role_name_migration import ShortRoleNameMigration | from bot_data.migration.short_role_name_migration import ShortRoleNameMigration | ||||||
| from bot_data.migration.short_role_name_only_highest_migration import ( | from bot_data.migration.short_role_name_only_highest_migration import ShortRoleNameOnlyHighestMigration | ||||||
|     ShortRoleNameOnlyHighestMigration, |  | ||||||
| ) |  | ||||||
| from bot_data.migration.stats_migration import StatsMigration | from bot_data.migration.stats_migration import StatsMigration | ||||||
| from bot_data.migration.steam_special_offer_migration import SteamSpecialOfferMigration | from bot_data.migration.user_joined_game_server_migration import UserJoinedGameServerMigration | ||||||
| from bot_data.migration.user_joined_game_server_migration import ( |  | ||||||
|     UserJoinedGameServerMigration, |  | ||||||
| ) |  | ||||||
| from bot_data.migration.user_message_count_per_hour_migration import ( | from bot_data.migration.user_message_count_per_hour_migration import ( | ||||||
|     UserMessageCountPerHourMigration, |     UserMessageCountPerHourMigration, | ||||||
| ) | ) | ||||||
| @@ -67,8 +56,3 @@ class StartupMigrationExtension(StartupExtensionABC): | |||||||
|         services.add_transient(MigrationABC, ShortRoleNameMigration)  # 28.09.2023 #378 - 1.1.7 |         services.add_transient(MigrationABC, ShortRoleNameMigration)  # 28.09.2023 #378 - 1.1.7 | ||||||
|         services.add_transient(MigrationABC, FixUpdatesMigration)  # 28.09.2023 #378 - 1.1.7 |         services.add_transient(MigrationABC, FixUpdatesMigration)  # 28.09.2023 #378 - 1.1.7 | ||||||
|         services.add_transient(MigrationABC, ShortRoleNameOnlyHighestMigration)  # 02.10.2023 #391 - 1.1.9 |         services.add_transient(MigrationABC, ShortRoleNameOnlyHighestMigration)  # 02.10.2023 #391 - 1.1.9 | ||||||
|         services.add_transient(MigrationABC, FixUserHistoryMigration)  # 10.10.2023 #401 - 1.2.0 |  | ||||||
|         services.add_transient(MigrationABC, BirthdayMigration)  # 10.10.2023 #401 - 1.2.0 |  | ||||||
|         services.add_transient(MigrationABC, SteamSpecialOfferMigration)  # 10.10.2023 #188 - 1.2.0 |  | ||||||
|         services.add_transient(MigrationABC, MaxSteamOfferCountMigration)  # 04.11.2023 #188 - 1.2.0 |  | ||||||
|         services.add_transient(MigrationABC, MaintenanceModeMigration)  # 06.11.2023 #424 - 1.2.0 |  | ||||||
| @@ -8,7 +8,6 @@ from cpl_core.dependency_injection import ServiceCollectionABC | |||||||
| from cpl_core.environment import ApplicationEnvironmentABC | from cpl_core.environment import ApplicationEnvironmentABC | ||||||
| 
 | 
 | ||||||
| from bot_core.configuration.bot_logging_settings import BotLoggingSettings | from bot_core.configuration.bot_logging_settings import BotLoggingSettings | ||||||
| from bot_core.environment_variables import MAINTENANCE, MIGRATION_ONLY |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class StartupSettingsExtension(StartupExtensionABC): | class StartupSettingsExtension(StartupExtensionABC): | ||||||
| @@ -18,14 +17,8 @@ class StartupSettingsExtension(StartupExtensionABC): | |||||||
|     def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC): |     def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC): | ||||||
|         # this shit has to be done here because we need settings in subsequent startup extensions |         # this shit has to be done here because we need settings in subsequent startup extensions | ||||||
|         environment.set_working_directory(os.path.dirname(os.path.realpath(__file__))) |         environment.set_working_directory(os.path.dirname(os.path.realpath(__file__))) | ||||||
|         configuration.add_environment_variables("SDB_") |         configuration.add_environment_variables("KDB_") | ||||||
|         configuration.add_environment_variables("DISCORD_") |         configuration.add_environment_variables("DISCORD_") | ||||||
|         configuration.add_configuration( |  | ||||||
|             MAINTENANCE, configuration.get_configuration(MAINTENANCE) in [True, "true", "True"] |  | ||||||
|         ) |  | ||||||
|         configuration.add_configuration( |  | ||||||
|             MIGRATION_ONLY, configuration.get_configuration(MIGRATION_ONLY) in [True, "true", "True"] |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|         configuration.add_json_file(f"config/appsettings.json", optional=False) |         configuration.add_json_file(f"config/appsettings.json", optional=False) | ||||||
|         configuration.add_json_file(f"config/appsettings.{environment.environment_name}.json", optional=True) |         configuration.add_json_file(f"config/appsettings.{environment.environment_name}.json", optional=True) | ||||||
| @@ -90,16 +90,10 @@ | |||||||
|       "booting": "Ich fahre gerade hoch...", |       "booting": "Ich fahre gerade hoch...", | ||||||
|       "restart": "Muss neue Kekse holen...", |       "restart": "Muss neue Kekse holen...", | ||||||
|       "running": "Ich esse Kekse :D", |       "running": "Ich esse Kekse :D", | ||||||
|       "shutdown": "Ich werde bestimmt wieder kommen...", |       "shutdown": "Ich werde bestimmt wieder kommen..." | ||||||
|       "maintenance": "In Wartung!" |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "modules": { |   "modules": { | ||||||
|     "special_offers": { |  | ||||||
|       "price": "Preis", |  | ||||||
|       "discount": "Rabatt", |  | ||||||
|       "discount_price": "Neuer Preis" |  | ||||||
|     }, |  | ||||||
|     "achievements": { |     "achievements": { | ||||||
|       "commands": { |       "commands": { | ||||||
|         "check": "Alles klar, ich schaue eben nach... nom nom" |         "check": "Alles klar, ich schaue eben nach... nom nom" | ||||||
| @@ -235,11 +229,6 @@ | |||||||
|         "success": "Verlinkung wurde entfernt :D" |         "success": "Verlinkung wurde entfernt :D" | ||||||
|       }, |       }, | ||||||
|       "user": { |       "user": { | ||||||
|         "birthday": { |  | ||||||
|           "has_birthday": "Alles Gute zum Geburtag {} :D", |  | ||||||
|           "success": "Dein Geburtstag wurde eingetragen.", |  | ||||||
|           "success_team": "{} hat seinen Geburtstag eingetragen: {}" |  | ||||||
|         }, |  | ||||||
|         "add": { |         "add": { | ||||||
|           "xp": "Die {} von {} wurden um {} erhöht" |           "xp": "Die {} von {} wurden um {} erhöht" | ||||||
|         }, |         }, | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -149,10 +149,7 @@ class Api(Flask): | |||||||
|         return response |         return response | ||||||
| 
 | 
 | ||||||
|     def start(self): |     def start(self): | ||||||
|         self._logger.info( |         self._logger.info(__name__, f"Starting API {self._api_settings.host}:{self._api_settings.port}") | ||||||
|             __name__, |  | ||||||
|             f"Starting API {self._api_settings.host}:{self._api_settings.port}", |  | ||||||
|         ) |  | ||||||
|         self._register_routes() |         self._register_routes() | ||||||
|         self.secret_key = CredentialManager.decrypt(self._auth_settings.secret_key) |         self.secret_key = CredentialManager.decrypt(self._auth_settings.secret_key) | ||||||
|         # from waitress import serve |         # from waitress import serve | ||||||
| @@ -48,4 +48,4 @@ class ApiModule(ModuleABC): | |||||||
|         services.add_transient(GraphQLController) |         services.add_transient(GraphQLController) | ||||||
| 
 | 
 | ||||||
|         # cpl-discord |         # cpl-discord | ||||||
|         services.add_transient(DiscordEventTypesEnum.on_ready.value, BotApiOnReadyEvent) |         self._dc.add_event(DiscordEventTypesEnum.on_ready.value, BotApiOnReadyEvent) | ||||||
| @@ -3,8 +3,8 @@ | |||||||
|     "Name": "bot-api", |     "Name": "bot-api", | ||||||
|     "Version": { |     "Version": { | ||||||
|       "Major": "1", |       "Major": "1", | ||||||
|       "Minor": "2", |       "Minor": "1", | ||||||
|       "Micro": "0" |       "Micro": "9" | ||||||
|     }, |     }, | ||||||
|     "Author": "", |     "Author": "", | ||||||
|     "AuthorEmail": "", |     "AuthorEmail": "", | ||||||
							
								
								
									
										1
									
								
								kdb-bot/src/bot_api/config
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								kdb-bot/src/bot_api/config
									
									
									
									
									
										Submodule
									
								
							 Submodule kdb-bot/src/bot_api/config added at b6ffed4da1
									
								
							| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
| @@ -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.0" | __version__ = "1.1.9" | ||||||
| 
 | 
 | ||||||
| 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="0") | version_info = VersionInfo(major="1", minor="1", micro="9") | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user