44 Commits

Author SHA1 Message Date
a869ee4780 Merge pull request '#293_complaints' (#326) from #293_complaints into 1.1.0
Reviewed-on: sh-edraft.de/kd_discord_bot#326
Reviewed-by: edraft-dev <dev.sven.heidemann@sh-edraft.de>
2023-08-14 09:37:08 +02:00
5776854494 Merge branch '1.1.0' into #293_complaints 2023-08-14 09:36:27 +02:00
5c820214a1 Merge pull request '#268_achievements' (#325) from #268_achievements into 1.1.0
Reviewed-on: sh-edraft.de/kd_discord_bot#325
Reviewed-by: edraft-dev <dev.sven.heidemann@sh-edraft.de>
2023-08-14 09:36:20 +02:00
f11d9af6c7 Fixed workspace #268_achievements 2023-08-14 09:35:46 +02:00
bff435d51e Added bug report #293_complaints 2023-07-18 11:43:50 +02:00
0f67bf467a Improved complaint command #293_complaints 2023-07-18 11:30:05 +02:00
2c7e5edbd7 [UNTESTED] Added complaint command #293_complaints 2023-07-18 11:15:20 +02:00
0846bbb29b Added achievements to data integrity service #268_achievements 2023-07-18 11:14:29 +02:00
926323252a Add xp for achievement #268_achievements 2023-07-18 11:06:12 +02:00
fedf2f4b8b Added description to achievements #268_achievements 2023-07-18 11:06:12 +02:00
4d4320dbcd Added history for achievements to frontend #268_achievements 2023-07-18 11:06:12 +02:00
c0b7e0913c Fixed achievements in user profile #268_achievements 2023-07-18 11:06:12 +02:00
9dcb75109f Added achievements to user profile #268_achievements 2023-07-18 11:06:12 +02:00
67baf350fa Added last_single_ontime_hours achievement logic #268_achievements 2023-07-18 11:06:12 +02:00
642a4d4dac Added played_on_game_server achievement logic #268_achievements 2023-07-18 11:06:12 +02:00
6b86cc3ca8 Improved generic achievement logic #268_achievements 2023-07-18 11:06:11 +02:00
fd10614b20 Improved internal achievement checks #268_achievements 2023-07-18 11:06:11 +02:00
0ec67d41e2 Added logic to make achievement config more generic #268_achievements 2023-07-18 11:06:11 +02:00
51928dcb4d Fixed config #268_achievements 2023-07-18 11:06:11 +02:00
e36f0b8c76 Improved achievement logic #268_achievements 2023-07-18 11:06:11 +02:00
2578c47c44 Improved achievement endpoint #268_achievements 2023-07-18 11:06:11 +02:00
dda2e2f5f6 Improved achievement component #268_achievements 2023-07-18 11:06:11 +02:00
8aa96482c1 Fixed server cache & improved frontend implementation #268_achievements 2023-07-18 11:06:11 +02:00
109bbf3729 First step to add achievements to frontend #268_achievements 2023-07-18 11:06:11 +02:00
3db548fb86 Fixed achievement query #268_achievements 2023-07-18 11:06:11 +02:00
0e5ec588fc Fixed achievement query #268_achievements 2023-07-18 11:06:11 +02:00
2c9434396d Added achievement gql endpoint [UNTESTED] #268_achievements 2023-07-18 11:06:11 +02:00
a49188b412 Fixed models #268_achievements 2023-07-18 11:06:11 +02:00
9e9879497a Added achievement data model #268_achievements 2023-07-18 11:06:11 +02:00
95e766d023 Merge pull request '#292_shutdown_procedure' (#321) from #292_shutdown_procedure into 1.1.0
Reviewed-on: sh-edraft.de/kd_discord_bot#321
Reviewed-by: Ebola-Chan <nick.jungmann@gmail.com>
Closes #292
2023-07-18 11:03:16 +02:00
e25c29b2a6 Merge branch '1.1.0' into #292_shutdown_procedure 2023-07-18 11:03:00 +02:00
1dd6db4c85 Merge pull request 'Fixed gql playground' (#322) from 1.1.0_fix_playground into 1.1.0
Reviewed-on: sh-edraft.de/kd_discord_bot#322
Reviewed-by: Ebola-Chan <nick.jungmann@gmail.com>
2023-06-26 10:27:51 +02:00
9a51e51235 Fixed gql playground 2023-06-18 18:51:36 +02:00
fe5f3ced39 Merge branch '1.1.0' into #292_shutdown_procedure 2023-06-16 10:40:18 +02:00
c1ec7dd97b Merge pull request 'Updated packages #297_cpl_update' (#320) from #297_cpl_update into 1.1.0
Reviewed-on: sh-edraft.de/kd_discord_bot#320
Reviewed-by: Ebola-Chan <nick.jungmann@gmail.com>
2023-06-16 10:39:33 +02:00
09771ac2a3 Ensure bot shutdown before data checks #292_shutdown_procedure 2023-06-14 11:48:49 +02:00
6f27ce7bbc Improved open voice state check #292_shutdown_procedure 2023-06-14 09:34:31 +02:00
806144d9d3 Added data integrity check to shutdown #292_shutdown_procedure 2023-06-14 09:29:07 +02:00
877af6b945 Moved data integrity check #292_shutdown_procedure 2023-06-14 09:25:54 +02:00
979e0a0e6f Removed comments #297_cpl_update 2023-06-14 09:00:19 +02:00
fdf10f2728 Updated cpl-discord #297_cpl_update 2023-06-13 16:24:38 +02:00
f7ffd78dcc Updated stuff #297_cpl_update 2023-06-13 16:16:52 +02:00
8ddb9f087a Updated packages #297_cpl_update 2023-06-12 20:52:01 +02:00
0ca3be478b Merge pull request 'Added reaction channel null check #318' (#319) from #318 into 1.1.0
Reviewed-on: sh-edraft.de/kd_discord_bot#319
2023-06-08 08:48:31 +02:00
891 changed files with 4027 additions and 15301 deletions

View File

@@ -1,17 +0,0 @@
#### Beschreibung
Als Produktmanager muss ich nun dieses Ticket ausfüllen.
#### Aktuelles Verhalten
* Was macht die Software aktuell?
#### Gewünschtes Verhalten
* Was soll die Software anders machen?
#### Akzeptanzkriterien
* Was muss erfüllt sein, damit das Ticket als abgeschlossen angesehen werden kann?
#### Anmerkungen

View File

@@ -1,7 +0,0 @@
#### Ticket Referenz:
#1
#### Gibt es etwas beim Review zu beachten?
Nein

View File

@@ -1,71 +0,0 @@
name: Deploy dev on push
run-name: Deploy dev on push
on:
push:
branches:
- dev
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_dev
- name: Build docker bot
run: |
cd bot
docker image prune -f
cpl build
docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-dev .
- name: Build docker web
run: |
cd web
docker image prune -f
cp src/favicon.dev.ico src/favicon.ico
npm run build
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-dev .
- name: Set version
run: |
cd bot/docker
chmod +x ./set-docker-compose-image-version.sh
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-dev sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-dev
- name: Deploy Stack to sh-edraft.de
uses: https://github.com/kgierke/portainer-stack-deployment@v1
with:
portainer-url: "https://docker.sh-edraft.de"
portainer-username: "gitea_job"
portainer-password: "${{ secrets.docker_job }}"
portainer-endpoint: 2
name: sdb_dev
file: bot/docker/docker-compose.dev.yml
variables: '{}'

View File

@@ -1,70 +0,0 @@
name: Deploy prod on push
run-name: Deploy prod on push
on:
push:
branches:
- master
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_prod
- name: Build docker bot
run: |
cd bot
docker image prune -f
cpl build
docker build -t sh-edraft.de/sdb-bot:$(cpl gv) .
- name: Build docker web
run: |
cd web
docker image prune -f
npm run build
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv) .
- name: Set version
run: |
cd bot/docker
chmod +x ./set-docker-compose-image-version.sh
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv) sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)
- name: Deploy Stack to sh-edraft.de
uses: https://github.com/kgierke/portainer-stack-deployment@v1
with:
portainer-url: "https://docker.sh-edraft.de"
portainer-username: "gitea_job"
portainer-password: "${{ secrets.docker_job }}"
portainer-endpoint: 2
name: sdb_prod
file: bot/docker/docker-compose.yml
variables: '{}'

View File

@@ -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
View File

@@ -1,9 +1,9 @@
[submodule "bot/src/bot/config"]
path = bot/src/bot/config
url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.config.git
[submodule "bot/src/bot_api/config"]
path = bot/src/bot_api/config
url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.api.config.git
[submodule "bot/docker"]
path = bot/docker
url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.docker.git
[submodule "kdb-bot/src/bot/config"]
path = kdb-bot/src/bot/config
url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.config.git
[submodule "kdb-bot/src/bot_api/config"]
path = kdb-bot/src/bot_api/config
url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.api.config.git
[submodule "kdb-bot/docker"]
path = kdb-bot/docker
url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.docker.git

View File

@@ -1,100 +0,0 @@
from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC
class DBTable(GenerateSchematicABC):
def __init__(self, *args: str):
GenerateSchematicABC.__init__(self, *args)
self._name = self._name.replace("_db_table", "")
self._class_name = self._class_name.split("Db_table")[0]
def get_code(self) -> str:
import textwrap
code = textwrap.dedent(
"""\
from datetime import datetime
from cpl_core.database import TableABC
class $ClassName(TableABC):
def __init__(
self,
value: str,
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._value = value
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 value(self) -> str:
return self._value
@value.setter
def value(self, value: str):
self._value = value
@staticmethod
def get_select_all_string() -> str:
return str(
f\"""
SELECT * FROM `$TableName`;
\"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f\"""
SELECT * FROM `$TableName`
WHERE `Id` = {id};
\"""
)
@property
def insert_string(self) -> str:
return str(
f\"""
INSERT INTO `$TableName` (
`Value`
) VALUES (
{self._value}
);
\"""
)
@property
def udpate_string(self) -> str:
return str(
f\"""
UPDATE `$TableName`
SET `Value` = {self._value}
WHERE `Id` = {self._id};
\"""
)
@property
def delete_string(self) -> str:
return str(
f\"""
DELETE FROM `$TableName`
WHERE `Id` = {self._id};
\"""
)
"""
)
return self.build_code_str(
code,
ClassName=self._class_name,
TableName=self._class_name,
)
@classmethod
def register(cls):
GenerateSchematicABC.register(cls, "db-table", [])

View File

@@ -1,55 +0,0 @@
from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC
class Migration(GenerateSchematicABC):
def __init__(self, *args: str):
GenerateSchematicABC.__init__(self, *args)
def get_code(self) -> str:
import textwrap
code = textwrap.dedent(
"""\
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.abc.migration_abc import MigrationABC
from bot_data.db_context import DBContext
class $ClassName(MigrationABC):
name = "1.0_$ClassName"
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 `$TableName` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY(`Id`)
);
\"""
)
)
def downgrade(self):
self._cursor.execute("DROP TABLE `$TableName`;")
"""
)
return self.build_code_str(
code,
ClassName=self._class_name,
TableName=self._class_name.split("Migration")[0],
)
@classmethod
def register(cls):
GenerateSchematicABC.register(cls, "migration", [])

Submodule bot/docker deleted from 9c0dc59534

View File

@@ -1,22 +0,0 @@
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
class ApiSettings(ConfigurationModelABC):
def __init__(self, port: int = None, host: str = None, redirect_uri: bool = None):
ConfigurationModelABC.__init__(self)
self._port = 80 if port is None else port
self._host = "" if host is None else host
self._redirect_to_https = False if redirect_uri is None else redirect_uri
@property
def port(self) -> int:
return self._port
@property
def host(self) -> str:
return self._host
@property
def redirect_to_https(self) -> bool:
return self._redirect_to_https

View File

@@ -1,39 +0,0 @@
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
class AuthenticationSettings(ConfigurationModelABC):
def __init__(
self,
secret_key: str = None,
issuer: str = None,
audience: str = None,
token_expire_time: int = None,
refresh_token_expire_time: int = None,
):
ConfigurationModelABC.__init__(self)
self._secret_key = "" if secret_key is None else secret_key
self._issuer = "" if issuer is None else issuer
self._audience = "" if audience is None else audience
self._token_expire_time = 0 if token_expire_time is None else token_expire_time
self._refresh_token_expire_time = 0 if refresh_token_expire_time is None else refresh_token_expire_time
@property
def secret_key(self) -> str:
return self._secret_key
@property
def issuer(self) -> str:
return self._issuer
@property
def audience(self) -> str:
return self._audience
@property
def token_expire_time(self) -> int:
return self._token_expire_time
@property
def refresh_token_expire_time(self) -> int:
return self._refresh_token_expire_time

View File

@@ -1,40 +0,0 @@
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
from cpl_query.extension import List
class DiscordAuthenticationSettings(ConfigurationModelABC):
def __init__(
self,
client_secret: str = None,
redirect_uri: str = None,
scope: list = None,
token_url: str = None,
auth_url: str = None,
):
ConfigurationModelABC.__init__(self)
self._client_secret = "" if client_secret is None else client_secret
self._redirect_url = "" if redirect_uri is None else redirect_uri
self._scope = List() if scope is None else List(str, scope)
self._token_url = "" if token_url is None else token_url
self._auth_url = "" if auth_url is None else auth_url
@property
def client_secret(self) -> str:
return self._client_secret
@property
def redirect_url(self) -> str:
return self._redirect_url
@property
def scope(self) -> List[str]:
return self._scope
@property
def token_url(self) -> str:
return self._token_url
@property
def auth_url(self) -> str:
return self._auth_url

View File

@@ -1,12 +0,0 @@
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
class FrontendSettings(ConfigurationModelABC):
def __init__(self, url: str = None):
ConfigurationModelABC.__init__(self)
self._url = "" if url is None else url
@property
def url(self) -> str:
return self._url

View File

@@ -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()

View File

@@ -1,63 +0,0 @@
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
class FeatureFlagsSettings(ConfigurationModelABC):
_flags = {
# modules
FeatureFlagsEnum.achievements_module.value: False, # 14.06.2023 #268
FeatureFlagsEnum.api_module.value: False, # 13.10.2022 #70
FeatureFlagsEnum.auto_role_module.value: False, # 03.10.2022 #54
FeatureFlagsEnum.base_module.value: True, # 02.10.2022 #48
FeatureFlagsEnum.boot_log_module.value: True, # 02.10.2022 #48
FeatureFlagsEnum.core_module.value: True, # 03.10.2022 #56
FeatureFlagsEnum.core_extension_module.value: True, # 03.10.2022 #56
FeatureFlagsEnum.data_module.value: True, # 03.10.2022 #56
FeatureFlagsEnum.database_module.value: True, # 02.10.2022 #48
FeatureFlagsEnum.moderator_module.value: False, # 02.10.2022 #48
FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48
FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127
FeatureFlagsEnum.short_role_name_module.value: True, # 28.09.2023 #378
FeatureFlagsEnum.steam_special_offers_module.value: True, # 11.10.2023 #188
# features
FeatureFlagsEnum.api_only.value: False, # 13.10.2022 #70
FeatureFlagsEnum.presence.value: True, # 03.10.2022 #56
FeatureFlagsEnum.version_in_presence.value: False, # 21.03.2023 #253
FeatureFlagsEnum.game_server.value: False, # 25.09.2023 #366
FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
FeatureFlagsEnum.steam_special_offers.value: False, # 11.10.2023 #188
}
def __init__(self, **kwargs: dict):
ConfigurationModelABC.__init__(self)
if len(kwargs.keys()) == 0:
return
for flag in [f.value for f in FeatureFlagsEnum]:
self._load_flag(kwargs, FeatureFlagsEnum(flag))
@classmethod
def get_flag_from_dict(cls, flags: dict, key: FeatureFlagsEnum) -> bool:
def get_flag():
if key.value not in cls._flags:
return False
return cls._flags[key.value]
if key.value not in flags:
return get_flag()
return flags[key.value]
def get_flag(self, key: FeatureFlagsEnum) -> bool:
if key.value not in self._flags:
return False
return self._flags[key.value]
def _load_flag(self, settings: dict, key: FeatureFlagsEnum):
if key.value not in settings:
return
self._flags[key.value] = bool(settings[key.value])

View File

@@ -1,2 +0,0 @@
MIGRATION_ONLY = "MIGRATION_ONLY"
MAINTENANCE = "MAINTENANCE"

View File

@@ -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)

View File

@@ -1,52 +0,0 @@
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
from bot_data.model.server import Server
from bot_data.model.technician_config import TechnicianConfig
from bot_data.service.server_config_seeder import ServerConfigSeeder
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
class ConfigService:
def __init__(
self,
config: ConfigurationABC,
services: ServiceProviderABC,
technician_config_repo: TechnicianConfigRepositoryABC,
server_config_repo: ServerConfigRepositoryABC,
technician_seeder: TechnicianConfigSeeder,
server_seeder: ServerConfigSeeder,
):
self._config = config
self._services = services
self._technician_config_repo = technician_config_repo
self._technician_seeder = technician_seeder
self._server_config_repo = server_config_repo
self._server_seeder = server_seeder
async def reload_technician_config(self):
try:
technician_config = self._technician_config_repo.get_technician_config()
except Exception as e:
await self._technician_seeder.seed()
technician_config = self._technician_config_repo.get_technician_config()
self._config.add_configuration(TechnicianConfig, technician_config)
self._config.add_configuration(
FeatureFlagsSettings,
FeatureFlagsSettings(**technician_config.feature_flags),
)
async def reload_server_config(self, server: Server):
if not self._server_config_repo.does_server_config_exists(server.id):
await self._server_seeder.seed()
server_config = self._server_config_repo.get_server_config_by_server(server.id)
self._config.add_configuration(
f"{type(server_config).__name__}_{server_config.server.discord_id}",
server_config,
)

View File

@@ -1,32 +0,0 @@
import os
from abc import ABC, abstractmethod
from cpl_core.dependency_injection import ServiceProviderABC
from mysql.connector.cursor import MySQLCursorBuffered
from bot_data.db_context import DBContext
class MigrationABC(ABC):
name = None
prio = 0
@abstractmethod
@ServiceProviderABC.inject
def __init__(self, db: DBContext):
self._cursor: MySQLCursorBuffered = db.cursor
@abstractmethod
def upgrade(self):
pass
@abstractmethod
def downgrade(self):
pass
def _exec(self, self_file: str, file: str):
path = f"{os.path.dirname(os.path.realpath(self_file))}/db_history_scripts"
sql = open(f"{path}/{file}").read()
for statement in sql.split("\n\n"):
self._cursor.execute(statement + ";")

View File

@@ -1,59 +0,0 @@
from abc import ABC, abstractmethod
from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig
from bot_data.model.server_config import ServerConfig
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
class ServerConfigRepositoryABC(ABC):
@abstractmethod
def __init__(self):
pass
@abstractmethod
def does_server_config_exists(self, server_id: int) -> bool:
pass
@abstractmethod
def get_server_config_by_server(self, server_id: int) -> ServerConfig:
pass
@abstractmethod
def get_server_config_by_id(self, config_id: int) -> ServerConfig:
pass
@abstractmethod
def add_server_config(self, server_config: ServerConfig):
pass
@abstractmethod
def update_server_config(self, server_config: ServerConfig):
pass
@abstractmethod
def delete_server_config(self, server_config: ServerConfig):
pass
@abstractmethod
def add_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
pass
@abstractmethod
def update_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
pass
@abstractmethod
def delete_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
pass
@abstractmethod
def add_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
pass
@abstractmethod
def update_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
pass
@abstractmethod
def delete_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
pass

View File

@@ -1,39 +0,0 @@
from abc import ABC, abstractmethod
from cpl_query.extension import List
from bot_data.model.short_role_name import ShortRoleName
class ShortRoleNameRepositoryABC(ABC):
@abstractmethod
def __init__(self):
pass
@abstractmethod
def get_short_role_names(self) -> List[ShortRoleName]:
pass
@abstractmethod
def get_short_role_name_by_id(self, id: int) -> ShortRoleName:
pass
@abstractmethod
def find_short_role_names_by_role_id(self, role_id: int) -> List[ShortRoleName]:
pass
@abstractmethod
def get_short_role_names_by_server_id(self, id: int) -> List[ShortRoleName]:
pass
@abstractmethod
def add_short_role_name(self, short_role_name: ShortRoleName):
pass
@abstractmethod
def update_short_role_name(self, short_role_name: ShortRoleName):
pass
@abstractmethod
def delete_short_role_name(self, short_role_name: ShortRoleName):
pass

View File

@@ -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

View File

@@ -1,55 +0,0 @@
from abc import ABC, abstractmethod
from bot_data.model.technician_config import TechnicianConfig
from bot_data.model.technician_id_config import TechnicianIdConfig
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
class TechnicianConfigRepositoryABC(ABC):
@abstractmethod
def __init__(self):
pass
@abstractmethod
def does_technician_config_exists(self) -> bool:
pass
@abstractmethod
def get_technician_config(self) -> TechnicianConfig:
pass
@abstractmethod
def add_technician_config(self, technician_config: TechnicianConfig):
pass
@abstractmethod
def update_technician_config(self, technician_config: TechnicianConfig):
pass
@abstractmethod
def delete_technician_config(self, technician_config: TechnicianConfig):
pass
@abstractmethod
def add_technician_id_config(self, technician_id: TechnicianIdConfig):
pass
@abstractmethod
def update_technician_id_config(self, technician_id: TechnicianIdConfig):
pass
@abstractmethod
def delete_technician_id_config(self, technician_id: TechnicianIdConfig):
pass
@abstractmethod
def add_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
pass
@abstractmethod
def update_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
pass
@abstractmethod
def delete_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
pass

View File

@@ -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;
"""
)
)

View File

@@ -1,29 +0,0 @@
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.abc.migration_abc import MigrationABC
from bot_data.db_context import DBContext
class ConfigFeatureFlagsMigration(MigrationABC):
name = "1.1.0_ConfigFeatureFlagsMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self)
self._logger = logger
self._db = db
self._cursor = db.cursor
def upgrade(self):
self._logger.debug(__name__, "Running upgrade")
self._cursor.execute(
str("""ALTER TABLE CFG_Technician ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;""")
)
self._cursor.execute(
str("""ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;""")
)
def downgrade(self):
self._logger.debug(__name__, "Running downgrade")
self._cursor.execute("ALTER TABLE CFG_Technician DROP COLUMN FeatureFlags;")
self._cursor.execute("ALTER TABLE CFG_Server DROP COLUMN FeatureFlags;")

View File

@@ -1,145 +0,0 @@
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.abc.migration_abc import MigrationABC
from bot_data.db_context import DBContext
class ConfigMigration(MigrationABC):
name = "1.1.0_ConfigMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self)
self._logger = logger
self._db = db
def upgrade(self):
self._logger.debug(__name__, "Running upgrade")
self._server_upgrade()
self._technician_upgrade()
self._exec(__file__, "config/server.sql")
self._exec(__file__, "config/server_afk_channels.sql")
self._exec(__file__, "config/server_team_roles.sql")
self._exec(__file__, "config/technician.sql")
self._exec(__file__, "config/technician_ids.sql")
self._exec(__file__, "config/technician_ping_urls.sql")
def _server_upgrade(self):
self._cursor.execute(
str(
f"""
CREATE TABLE IF NOT EXISTS `CFG_Server` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`MessageDeleteTimer` BIGINT NOT NULL DEFAULT 6,
`NotificationChatId` BIGINT NOT NULL,
`MaxVoiceStateHours` BIGINT NOT NULL DEFAULT 6,
`XpPerMessage` BIGINT NOT NULL DEFAULT 1,
`XpPerReaction` BIGINT NOT NULL DEFAULT 1,
`MaxMessageXpPerHour` BIGINT NOT NULL DEFAULT 20,
`XpPerOntimeHour` BIGINT NOT NULL DEFAULT 10,
`XpPerEventParticipation` BIGINT NOT NULL DEFAULT 10,
`XpPerAchievement` BIGINT NOT NULL DEFAULT 10,
`AFKCommandChannelId` BIGINT NOT NULL,
`HelpVoiceChannelId` BIGINT NOT NULL,
`TeamChannelId` BIGINT NOT NULL,
`LoginMessageChannelId` BIGINT NOT NULL,
`ServerId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY(`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
);
"""
)
)
self._cursor.execute(
str(
f"""
CREATE TABLE IF NOT EXISTS `CFG_ServerAFKChannelIds` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`ChannelId` BIGINT NOT NULL,
`ServerId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY(`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
);
"""
)
)
self._cursor.execute(
str(
f"""
CREATE TABLE IF NOT EXISTS `CFG_ServerTeamRoleIds` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`RoleId` BIGINT NOT NULL,
`TeamMemberType` ENUM('Moderator', 'Admin') NOT NULL,
`ServerId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY(`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
);
"""
)
)
def _technician_upgrade(self):
self._cursor.execute(
str(
f"""
CREATE TABLE IF NOT EXISTS `CFG_Technician` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`HelpCommandReferenceUrl` VARCHAR(255) NOT NULL,
`WaitForRestart` BIGINT NOT NULL DEFAULT 8,
`WaitForShutdown` BIGINT NOT NULL DEFAULT 8,
`CacheMaxMessages` BIGINT NOT NULL DEFAULT 1000000,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY(`Id`)
);
"""
)
)
self._cursor.execute(
str(
f"""
CREATE TABLE IF NOT EXISTS `CFG_TechnicianPingUrls` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`URL` VARCHAR(255) NOT NULL,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY(`Id`)
);
"""
)
)
self._cursor.execute(
str(
f"""
CREATE TABLE IF NOT EXISTS `CFG_TechnicianIds` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`TechnicianId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY(`Id`)
);
"""
)
)
def downgrade(self):
self._logger.debug(__name__, "Running downgrade")
self._server_downgrade()
self._technician_downgrade()
def _server_downgrade(self):
self._cursor.execute("DROP TABLE `CFG_Server`;")
def _technician_downgrade(self):
self._cursor.execute("DROP TABLE `CFG_Technician`;")
self._cursor.execute("DROP TABLE `CFG_TechnicianPingUrls`;")
self._cursor.execute("DROP TABLE `CFG_TechnicianIds`;")

View File

@@ -1,124 +0,0 @@
CREATE TABLE IF NOT EXISTS `CFG_ServerHistory`
(
`Id` BIGINT(20) NOT NULL,
`MessageDeleteTimer` BIGINT NOT NULL DEFAULT 6,
`NotificationChatId` BIGINT NOT NULL,
`MaxVoiceStateHours` BIGINT NOT NULL DEFAULT 6,
`XpPerMessage` BIGINT NOT NULL DEFAULT 1,
`XpPerReaction` BIGINT NOT NULL DEFAULT 1,
`MaxMessageXpPerHour` BIGINT NOT NULL DEFAULT 20,
`XpPerOntimeHour` BIGINT NOT NULL DEFAULT 10,
`XpPerEventParticipation` BIGINT NOT NULL DEFAULT 10,
`XpPerAchievement` BIGINT NOT NULL DEFAULT 10,
`AFKCommandChannelId` BIGINT NOT NULL,
`HelpVoiceChannelId` BIGINT NOT NULL,
`TeamChannelId` BIGINT NOT NULL,
`LoginMessageChannelId` BIGINT NOT NULL,
`DefaultRoleId` BIGINT NULL,
`ShortRoleNameSetOnlyHighest` BOOLEAN NOT NULL DEFAULT FALSE,
`FeatureFlags` JSON NULL DEFAULT ('{}'),
`ServerId` BIGINT NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
DROP TRIGGER IF EXISTS `TR_CFG_ServerUpdate`;
CREATE TRIGGER `TR_CFG_ServerUpdate`
AFTER UPDATE
ON `CFG_Server`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_ServerHistory` (`Id`,
`MessageDeleteTimer`,
`NotificationChatId`,
`MaxVoiceStateHours`,
`XpPerMessage`,
`XpPerReaction`,
`MaxMessageXpPerHour`,
`XpPerOntimeHour`,
`XpPerEventParticipation`,
`XpPerAchievement`,
`AFKCommandChannelId`,
`HelpVoiceChannelId`,
`TeamChannelId`,
`LoginMessageChannelId`,
`DefaultRoleId`,
`ShortRoleNameSetOnlyHighest`,
`FeatureFlags`,
`ServerId`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.MessageDeleteTimer,
OLD.NotificationChatId,
OLD.MaxVoiceStateHours,
OLD.XpPerMessage,
OLD.XpPerReaction,
OLD.MaxMessageXpPerHour,
OLD.XpPerOntimeHour,
OLD.XpPerEventParticipation,
OLD.XpPerAchievement,
OLD.AFKCommandChannelId,
OLD.HelpVoiceChannelId,
OLD.TeamChannelId,
OLD.LoginMessageChannelId,
OLD.DefaultRoleId,
OLD.ShortRoleNameSetOnlyHighest,
OLD.FeatureFlags,
OLD.ServerId,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;
DROP TRIGGER IF EXISTS `TR_CFG_ServerDelete`;
CREATE TRIGGER `TR_CFG_ServerDelete`
AFTER DELETE
ON `CFG_Server`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_ServerHistory` (`Id`,
`MessageDeleteTimer`,
`NotificationChatId`,
`MaxVoiceStateHours`,
`XpPerMessage`,
`XpPerReaction`,
`MaxMessageXpPerHour`,
`XpPerOntimeHour`,
`XpPerEventParticipation`,
`XpPerAchievement`,
`AFKCommandChannelId`,
`HelpVoiceChannelId`,
`TeamChannelId`,
`LoginMessageChannelId`,
`DefaultRoleId`,
`ShortRoleNameSetOnlyHighest`,
`ServerId`,
`FeatureFlags`,
`Deleted`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.MessageDeleteTimer,
OLD.NotificationChatId,
OLD.MaxVoiceStateHours,
OLD.XpPerMessage,
OLD.XpPerReaction,
OLD.MaxMessageXpPerHour,
OLD.XpPerOntimeHour,
OLD.XpPerEventParticipation,
OLD.XpPerAchievement,
OLD.AFKCommandChannelId,
OLD.HelpVoiceChannelId,
OLD.TeamChannelId,
OLD.LoginMessageChannelId,
OLD.DefaultRoleId,
OLD.ShortRoleNameSetOnlyHighest,
OLD.FeatureFlags,
OLD.ServerId,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;

View File

@@ -1,57 +0,0 @@
CREATE TABLE IF NOT EXISTS `CFG_ServerAFKChannelIdsHistory`
(
`Id` BIGINT(20) NOT NULL,
`ChannelId` BIGINT NOT NULL,
`ServerId` BIGINT NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
DROP TRIGGER IF EXISTS `TR_CFG_ServerAFKChannelIdsUpdate`;
CREATE TRIGGER `TR_CFG_ServerAFKChannelIdsUpdate`
AFTER UPDATE
ON `CFG_ServerAFKChannelIds`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_ServerAFKChannelIdsHistory` (
`Id`,
`ChannelId`,
`ServerId`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.ChannelId,
OLD.ServerId,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;
DROP TRIGGER IF EXISTS `TR_CFG_ServerAFKChannelIdsDelete`;
CREATE TRIGGER `TR_CFG_ServerAFKChannelIdsDelete`
AFTER DELETE
ON `CFG_ServerAFKChannelIds`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_ServerAFKChannelIdsHistory` (
`Id`,
`ChannelId`,
`ServerId`,
`Deleted`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.ChannelId,
OLD.ServerId,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;

View File

@@ -1,62 +0,0 @@
CREATE TABLE IF NOT EXISTS `CFG_ServerTeamRoleIdsHistory`
(
`Id` BIGINT(20) NOT NULL,
`RoleId` BIGINT NOT NULL,
`TeamMemberType` ENUM('Moderator', 'Admin') NOT NULL,
`ServerId` BIGINT NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
DROP TRIGGER IF EXISTS `TR_CFG_ServerTeamRoleIdsUpdate`;
CREATE TRIGGER `TR_CFG_ServerTeamRoleIdsUpdate`
AFTER UPDATE
ON `CFG_ServerTeamRoleIds`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_ServerTeamRoleIdsHistory` (
`Id`,
`RoleId`,
`TeamMemberType`,
`ServerId`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.RoleId,
OLD.TeamMemberType,
OLD.ServerId,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;
DROP TRIGGER IF EXISTS `TR_CFG_ServerTeamRoleIdsDelete`;
CREATE TRIGGER `TR_CFG_ServerTeamRoleIdsDelete`
AFTER DELETE
ON `CFG_ServerTeamRoleIds`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_ServerTeamRoleIdsHistory` (
`Id`,
`RoleId`,
`TeamMemberType`,
`ServerId`,
`Deleted`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.RoleId,
OLD.TeamMemberType,
OLD.ServerId,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;

View File

@@ -1,74 +0,0 @@
CREATE TABLE IF NOT EXISTS `CFG_TechnicianHistory`
(
`Id` BIGINT(20) NOT NULL,
`HelpCommandReferenceUrl` VARCHAR(255) NOT NULL,
`WaitForRestart` BIGINT NOT NULL DEFAULT 8,
`WaitForShutdown` BIGINT NOT NULL DEFAULT 8,
`CacheMaxMessages` BIGINT NOT NULL DEFAULT 1000000,
`MaxSteamOfferCount` BIGINT NOT NULL DEFAULT 250,
`Maintenance` BOOLEAN DEFAULT FALSE,
`FeatureFlags` JSON NULL DEFAULT ('{}'),
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
DROP TRIGGER IF EXISTS `TR_CFG_TechnicianUpdate`;
CREATE TRIGGER `TR_CFG_TechnicianUpdate`
AFTER UPDATE
ON `CFG_Technician`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_TechnicianHistory` (`Id`,
`HelpCommandReferenceUrl`,
`WaitForRestart`,
`WaitForShutdown`,
`CacheMaxMessages`,
`MaxSteamOfferCount`,
`Maintenance`,
`FeatureFlags`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.HelpCommandReferenceUrl,
OLD.WaitForRestart,
OLD.WaitForShutdown,
OLD.CacheMaxMessages,
OLD.MaxSteamOfferCount,
OLD.Maintenance,
OLD.FeatureFlags,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;
DROP TRIGGER IF EXISTS `TR_CFG_TechnicianDelete`;
CREATE TRIGGER `TR_CFG_TechnicianDelete`
AFTER DELETE
ON `CFG_Technician`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_TechnicianHistory` (`Id`,
`HelpCommandReferenceUrl`,
`WaitForRestart`,
`WaitForShutdown`,
`CacheMaxMessages`,
`MaxSteamOfferCount`,
`Maintenance`,
`FeatureFlags`,
`Deleted`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.HelpCommandReferenceUrl,
OLD.WaitForRestart,
OLD.WaitForShutdown,
OLD.CacheMaxMessages,
OLD.MaxSteamOfferCount,
OLD.Maintenance,
OLD.FeatureFlags,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;

View File

@@ -1,52 +0,0 @@
CREATE TABLE IF NOT EXISTS `CFG_TechnicianIdsHistory`
(
`Id` BIGINT(20) NOT NULL,
`TechnicianId` BIGINT NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
DROP TRIGGER IF EXISTS `TR_CFG_TechnicianIdsUpdate`;
CREATE TRIGGER `TR_CFG_TechnicianIdsUpdate`
AFTER UPDATE
ON `CFG_TechnicianIds`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_TechnicianIdsHistory` (
`Id`,
`TechnicianId`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.TechnicianId,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;
DROP TRIGGER IF EXISTS `TR_CFG_TechnicianIdsDelete`;
CREATE TRIGGER `TR_CFG_TechnicianIdsDelete`
AFTER DELETE
ON `CFG_TechnicianIds`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_TechnicianIdsHistory` (
`Id`,
`TechnicianId`,
`Deleted`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.TechnicianId,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;

View File

@@ -1,52 +0,0 @@
CREATE TABLE IF NOT EXISTS `CFG_TechnicianPingUrlsHistory`
(
`Id` BIGINT(20) NOT NULL,
`URL` VARCHAR(255) NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
DROP TRIGGER IF EXISTS `TR_CFG_TechnicianPingUrlsUpdate`;
CREATE TRIGGER `TR_CFG_TechnicianPingUrlsUpdate`
AFTER UPDATE
ON `CFG_TechnicianPingUrls`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_TechnicianPingUrlsHistory` (
`Id`,
`URL`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.URL,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;
DROP TRIGGER IF EXISTS `TR_CFG_TechnicianPingUrlsDelete`;
CREATE TRIGGER `TR_CFG_TechnicianPingUrlsDelete`
AFTER DELETE
ON `CFG_TechnicianPingUrls`
FOR EACH ROW
BEGIN
INSERT INTO `CFG_TechnicianPingUrlsHistory` (
`Id`,
`URL`,
`Deleted`,
`DateFrom`,
`DateTo`
)
VALUES (
OLD.Id,
OLD.URL,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6)
);
END;

View File

@@ -1,38 +0,0 @@
CREATE TABLE IF NOT EXISTS `ShortRoleNamesHistory`
(
`Id` BIGINT(20) NOT NULL,
`ShortName` VARCHAR(64) DEFAULT NULL,
`DiscordRoleId` BIGINT(20) NOT NULL,
`Position` ENUM ('Before', 'After') NOT NULL,
`ServerId` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
DROP TRIGGER IF EXISTS `TR_ShortRoleNamesUpdate`;
CREATE TRIGGER `TR_ShortRoleNamesUpdate`
AFTER UPDATE
ON `ShortRoleNames`
FOR EACH ROW
BEGIN
INSERT INTO `ShortRoleNamesHistory` (`Id`, `ShortName`, `DiscordRoleId`, `Position`, `ServerId`, `DateFrom`,
`DateTo`)
VALUES (OLD.Id, OLD.ShortName, OLD.DiscordRoleId, OLD.Position, OLD.ServerId, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;
DROP TRIGGER IF EXISTS `TR_ShortRoleNamesDelete`;
CREATE TRIGGER `TR_ShortRoleNamesDelete`
AFTER DELETE
ON `ShortRoleNames`
FOR EACH ROW
BEGIN
INSERT INTO `ShortRoleNamesHistory` (`Id`, `ShortName`, `DiscordRoleId`, `Position`, `ServerId`, `Deleted`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id, OLD.ShortName, OLD.DiscordRoleId, OLD.Position, OLD.ServerId, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;

View File

@@ -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;

View File

@@ -1,34 +0,0 @@
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.abc.migration_abc import MigrationABC
from bot_data.db_context import DBContext
class DefaultRoleMigration(MigrationABC):
name = "1.1.3_DefaultRoleMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self)
self._logger = logger
self._db = db
self._cursor = db.cursor
def upgrade(self):
self._logger.debug(__name__, "Running upgrade")
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_Server
ADD DefaultRoleId BIGINT NULL AFTER LoginMessageChannelId;
"""
)
)
def downgrade(self):
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_Server DROP COLUMN DefaultRoleId;
"""
)
)

View File

@@ -1,51 +0,0 @@
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.abc.migration_abc import MigrationABC
from bot_data.db_context import DBContext
class FixUpdatesMigration(MigrationABC):
name = "1.1.7_FixUpdatesMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self)
self._logger = logger
self._db = db
self._cursor = db.cursor
def upgrade(self):
self._logger.debug(__name__, "Running upgrade")
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_ServerHistory
ADD DefaultRoleId BIGINT NULL AFTER LoginMessageChannelId;
"""
)
)
self._cursor.execute(
str(
"""ALTER TABLE CFG_TechnicianHistory ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;"""
)
)
self._cursor.execute(
str(
"""ALTER TABLE CFG_ServerHistory ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;"""
)
)
self._exec(__file__, "config/server.sql")
self._exec(__file__, "config/technician.sql")
def downgrade(self):
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_ServerHistory DROP COLUMN DefaultRoleId;
"""
)
)
self._cursor.execute("ALTER TABLE CFG_TechnicianHistory DROP COLUMN FeatureFlags;")
self._cursor.execute("ALTER TABLE CFG_ServerHistory DROP COLUMN FeatureFlags;")

View File

@@ -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;
"""
)
)

View File

@@ -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;
"""
)
)

View File

@@ -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;
"""
)
)

View File

@@ -1,40 +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 ShortRoleNameMigration(MigrationABC):
name = "1.1.7_ShortRoleNameMigration"
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 `ShortRoleNames` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`ShortName` VARCHAR(255) NOT NULL,
`DiscordRoleId` BIGINT NOT NULL,
`Position` ENUM('before', 'after') NOT NULL,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY(`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
);
"""
)
)
self._exec(__file__, "short_rule_names.sql")
def downgrade(self):
self._cursor.execute("DROP TABLE `ShortRoleNames`;")
self._cursor.execute("DROP TABLE `ShortRoleNamesHistory`;")

View File

@@ -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 ShortRoleNameOnlyHighestMigration(MigrationABC):
name = "1.1.9_ShortRoleNameOnlyHighestMigration"
def __init__(self, logger: DatabaseLogger, db: DBContext):
MigrationABC.__init__(self)
self._logger = logger
self._db = db
self._cursor = db.cursor
def upgrade(self):
self._logger.debug(__name__, "Running upgrade")
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_Server
ADD ShortRoleNameSetOnlyHighest BOOLEAN NOT NULL DEFAULT FALSE AFTER DefaultRoleId;
"""
)
)
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_ServerHistory
ADD ShortRoleNameSetOnlyHighest BOOLEAN NOT NULL DEFAULT FALSE AFTER DefaultRoleId;
"""
)
)
self._exec(__file__, "config/server.sql")
def downgrade(self):
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_Server DROP COLUMN ShortRoleNameSetOnlyHighest;
"""
)
)
self._cursor.execute(
str(
f"""
ALTER TABLE CFG_ServerHistory DROP COLUMN ShortRoleNameSetOnlyHighest;
"""
)
)

View File

@@ -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;
"""
)
)

View File

@@ -1,85 +0,0 @@
from datetime import datetime
from cpl_core.database import TableABC
class ServerAFKChannelIdsConfig(TableABC):
def __init__(
self,
channel_id: int,
server_id: int,
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._channel_id = channel_id
self._server_id = server_id
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 channel_id(self) -> int:
return self._channel_id
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `CFG_ServerAFKChannelIds`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_ServerAFKChannelIds`
WHERE `Id` = {id};
"""
)
@staticmethod
def get_select_by_server_id_string(server_id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_ServerAFKChannelIds`
WHERE `ServerId` = {server_id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `CFG_ServerAFKChannelIds` (
`ChannelId`,
`ServerId`
) VALUES (
{self._channel_id},
{self._server_id}
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `CFG_ServerAFKChannelIds`
SET `ChannelId` = {self._channel_id},
`ServerId` = {self._server_id}
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `CFG_ServerAFKChannelIds`
WHERE `ChannelId` = {self._channel_id};
"""
)

View File

@@ -1,374 +0,0 @@
import json
from datetime import datetime
from typing import Optional
from cpl_core.configuration import ConfigurationModelABC
from cpl_core.database import TableABC
from cpl_query.extension import List
from discord import Guild
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_data.model.server import Server
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
class ServerConfig(TableABC, ConfigurationModelABC):
def __init__(
self,
message_delete_timer: int,
notification_chat_id: int,
max_voice_state_hours: int,
xp_per_message: int,
xp_per_reaction: int,
max_message_xp_per_hour: int,
xp_per_ontime_hour: int,
xp_per_event_participation: int,
xp_per_achievement: int,
xp_for_birthday: int,
afk_command_channel_id: int,
help_voice_channel_id: int,
team_channel_id: int,
login_message_channel_id: int,
default_role_id: Optional[int],
short_role_name_only_set_highest_role: bool,
game_offer_notification_chat_id: int,
feature_flags: dict[FeatureFlagsEnum],
server: Server,
afk_channel_ids: List[int],
team_role_ids: List[ServerTeamRoleIdsConfig],
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._message_delete_timer = message_delete_timer
self._notification_chat_id = notification_chat_id
self._max_voice_state_hours = max_voice_state_hours
self._xp_per_message = xp_per_message
self._xp_per_reaction = xp_per_reaction
self._max_message_xp_per_hour = max_message_xp_per_hour
self._xp_per_ontime_hour = xp_per_ontime_hour
self._xp_per_event_participation = xp_per_event_participation
self._xp_per_achievement = xp_per_achievement
self._xp_for_birthday = xp_for_birthday
self._afk_command_channel_id = afk_command_channel_id
self._help_voice_channel_id = help_voice_channel_id
self._team_channel_id = team_channel_id
self._login_message_channel_id = login_message_channel_id
self._default_role_id = default_role_id
self._short_role_name_only_set_highest_role = short_role_name_only_set_highest_role
self._game_offer_notification_chat_id = game_offer_notification_chat_id
self._feature_flags = feature_flags
self._server = server
self._afk_channel_ids = afk_channel_ids
self._team_role_ids = team_role_ids
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
@staticmethod
def new(guild: Guild, server: Server) -> "ServerConfig":
return ServerConfig(
6,
guild.system_channel.id,
6,
1,
1,
20,
10,
10,
10,
10,
guild.system_channel.id,
guild.system_channel.id,
guild.system_channel.id,
guild.system_channel.id,
None,
False,
guild.system_channel.id,
{},
server,
List(int),
List(int),
)
@property
def id(self) -> int:
return self._id
@property
def message_delete_timer(self) -> int:
return self._message_delete_timer
@message_delete_timer.setter
def message_delete_timer(self, value: int):
self._message_delete_timer = value
@property
def notification_chat_id(self) -> int:
return self._notification_chat_id
@notification_chat_id.setter
def notification_chat_id(self, value: int):
self._notification_chat_id = value
@property
def max_voice_state_hours(self) -> int:
return self._max_voice_state_hours
@max_voice_state_hours.setter
def max_voice_state_hours(self, value: int):
self._max_voice_state_hours = value
@property
def xp_per_message(self) -> int:
return self._xp_per_message
@xp_per_message.setter
def xp_per_message(self, value: int):
self._xp_per_message = value
@property
def xp_per_reaction(self) -> int:
return self._xp_per_reaction
@xp_per_reaction.setter
def xp_per_reaction(self, value: int):
self._xp_per_reaction = value
@property
def max_message_xp_per_hour(self) -> int:
return self._max_message_xp_per_hour
@max_message_xp_per_hour.setter
def max_message_xp_per_hour(self, value: int):
self._max_message_xp_per_hour = value
@property
def xp_per_ontime_hour(self) -> int:
return self._xp_per_ontime_hour
@xp_per_ontime_hour.setter
def xp_per_ontime_hour(self, value: int):
self._xp_per_ontime_hour = value
@property
def xp_per_event_participation(self) -> int:
return self._xp_per_event_participation
@xp_per_event_participation.setter
def xp_per_event_participation(self, value: int):
self._xp_per_event_participation = value
@property
def xp_per_achievement(self) -> int:
return self._xp_per_achievement
@xp_per_achievement.setter
def xp_per_achievement(self, value: int):
self._xp_per_achievement = value
@property
def xp_for_birthday(self) -> int:
return self._xp_for_birthday
@xp_for_birthday.setter
def xp_for_birthday(self, value: int):
self._xp_for_birthday = value
@property
def afk_command_channel_id(self) -> int:
return self._afk_command_channel_id
@afk_command_channel_id.setter
def afk_command_channel_id(self, value: int):
self._afk_command_channel_id = value
@property
def help_voice_channel_id(self) -> int:
return self._help_voice_channel_id
@help_voice_channel_id.setter
def help_voice_channel_id(self, value: int):
self._help_voice_channel_id = value
@property
def team_channel_id(self) -> int:
return self._team_channel_id
@team_channel_id.setter
def team_channel_id(self, value: int):
self._team_channel_id = value
@property
def login_message_channel_id(self) -> int:
return self._login_message_channel_id
@login_message_channel_id.setter
def login_message_channel_id(self, value: int):
self._login_message_channel_id = value
@property
def default_role_id(self) -> int:
return self._default_role_id
@default_role_id.setter
def default_role_id(self, value: int):
self._default_role_id = value
@property
def short_role_name_only_set_highest_role(self) -> bool:
return self._short_role_name_only_set_highest_role
@short_role_name_only_set_highest_role.setter
def short_role_name_only_set_highest_role(self, value: bool):
self._short_role_name_only_set_highest_role = value
@property
def game_offer_notification_chat_id(self) -> int:
return self._game_offer_notification_chat_id
@game_offer_notification_chat_id.setter
def game_offer_notification_chat_id(self, value: int):
self._game_offer_notification_chat_id = value
@property
def feature_flags(self) -> dict[FeatureFlagsEnum]:
return self._feature_flags
@feature_flags.setter
def feature_flags(self, value: dict[FeatureFlagsEnum]):
self._feature_flags = value
@property
def afk_channel_ids(self) -> List[int]:
return self._afk_channel_ids
@afk_channel_ids.setter
def afk_channel_ids(self, value: List[int]):
self._afk_channel_ids = value
@property
def team_role_ids(self) -> List[ServerTeamRoleIdsConfig]:
return self._team_role_ids
@team_role_ids.setter
def team_role_ids(self, value: List[ServerTeamRoleIdsConfig]):
self._team_role_ids = value
@property
def server(self) -> Server:
return self._server
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `CFG_Server`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_Server`
WHERE `Id` = {id};
"""
)
@staticmethod
def get_select_by_server_id_string(server_id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_Server`
WHERE `ServerId` = {server_id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `CFG_Server` (
`MessageDeleteTimer`,
`NotificationChatId`,
`MaxVoiceStateHours`,
`XpPerMessage`,
`XpPerReaction`,
`MaxMessageXpPerHour`,
`XpPerOntimeHour`,
`XpPerEventParticipation`,
`XpPerAchievement`,
`XpForBirthday`,
`AFKCommandChannelId`,
`HelpVoiceChannelId`,
`TeamChannelId`,
`LoginMessageChannelId`,
`DefaultRoleId`,
`ShortRoleNameSetOnlyHighest`,
`GameOfferNotificationChatId`,
`FeatureFlags`,
`ServerId`
) VALUES (
{self._message_delete_timer},
{self._notification_chat_id},
{self._max_voice_state_hours},
{self._xp_per_message},
{self._xp_per_reaction},
{self._max_message_xp_per_hour},
{self._xp_per_ontime_hour},
{self._xp_per_event_participation},
{self._xp_per_achievement},
'{self._xp_for_birthday}',
{self._afk_command_channel_id},
{self._help_voice_channel_id},
{self._team_channel_id},
{self._login_message_channel_id},
{"NULL" if self._default_role_id is None else self._default_role_id},
{self._short_role_name_only_set_highest_role},
{self._game_offer_notification_chat_id},
'{json.dumps(self._feature_flags)}',
{self._server.id}
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `CFG_Server`
SET `MessageDeleteTimer` = {self._message_delete_timer},
`NotificationChatId` = {self._notification_chat_id},
`MaxVoiceStateHours` = {self._max_voice_state_hours},
`XpPerMessage` = {self._xp_per_message},
`XpPerReaction` = {self._xp_per_reaction},
`MaxMessageXpPerHour` = {self._max_message_xp_per_hour},
`XpPerOntimeHour` = {self._xp_per_ontime_hour},
`XpPerEventParticipation` = {self._xp_per_event_participation},
`XpPerAchievement` = {self._xp_per_achievement},
`XpForBirthday` = {self._xp_for_birthday},
`AFKCommandChannelId` = {self._afk_command_channel_id},
`HelpVoiceChannelId` = {self._help_voice_channel_id},
`TeamChannelId` = {self._team_channel_id},
`LoginMessageChannelId` = {self._login_message_channel_id},
`DefaultRoleId` = {"NULL" if self._default_role_id is None else self._default_role_id},
`ShortRoleNameSetOnlyHighest` = {self._short_role_name_only_set_highest_role},
`GameOfferNotificationChatId` = {self._game_offer_notification_chat_id},
`FeatureFlags` = '{json.dumps(self._feature_flags)}',
`ServerId` = {self._server.id}
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `CFG_Server`
WHERE `Id` = {self._id};
"""
)

View File

@@ -1,121 +0,0 @@
from bot_data.abc.history_table_abc import HistoryTableABC
class ServerConfigHistory(HistoryTableABC):
def __init__(
self,
message_delete_timer: int,
notification_chat_id: int,
max_voice_state_hours: int,
xp_per_message: int,
xp_per_reaction: int,
max_message_xp_per_hour: int,
xp_per_ontime_hour: int,
xp_per_event_participation: int,
xp_per_achievement: int,
afk_command_channel_id: int,
help_voice_channel_id: int,
team_channel_id: int,
login_message_channel_id: int,
default_role_id: int,
short_role_name_only_set_highest_role: bool,
feature_flags: dict[str],
server_id: int,
deleted: bool,
date_from: str,
date_to: str,
id=0,
):
HistoryTableABC.__init__(self)
self._id = id
self._message_delete_timer = message_delete_timer
self._notification_chat_id = notification_chat_id
self._max_voice_state_hours = max_voice_state_hours
self._xp_per_message = xp_per_message
self._xp_per_reaction = xp_per_reaction
self._max_message_xp_per_hour = max_message_xp_per_hour
self._xp_per_ontime_hour = xp_per_ontime_hour
self._xp_per_event_participation = xp_per_event_participation
self._xp_per_achievement = xp_per_achievement
self._afk_command_channel_id = afk_command_channel_id
self._help_voice_channel_id = help_voice_channel_id
self._team_channel_id = team_channel_id
self._login_message_channel_id = login_message_channel_id
self._default_role_id = default_role_id
self._short_role_name_only_set_highest_role = short_role_name_only_set_highest_role
self._feature_flags = feature_flags
self._server_id = server_id
self._deleted = deleted
self._date_from = date_from
self._date_to = date_to
@property
def message_delete_timer(self) -> int:
return self._message_delete_timer
@property
def notification_chat_id(self) -> int:
return self._notification_chat_id
@property
def max_voice_state_hours(self) -> int:
return self._max_voice_state_hours
@property
def xp_per_message(self) -> int:
return self._xp_per_message
@property
def xp_per_reaction(self) -> int:
return self._xp_per_reaction
@property
def max_message_xp_per_hour(self) -> int:
return self._max_message_xp_per_hour
@property
def xp_per_ontime_hour(self) -> int:
return self._xp_per_ontime_hour
@property
def xp_per_event_participation(self) -> int:
return self._xp_per_event_participation
@property
def xp_per_achievement(self) -> int:
return self._xp_per_achievement
@property
def afk_command_channel_id(self) -> int:
return self._afk_command_channel_id
@property
def help_voice_channel_id(self) -> int:
return self._help_voice_channel_id
@property
def team_channel_id(self) -> int:
return self._team_channel_id
@property
def login_message_channel_id(self) -> int:
return self._login_message_channel_id
@property
def default_role_id(self) -> int:
return self._default_role_id
@property
def short_role_name_only_set_highest_role(self) -> bool:
return self._short_role_name_only_set_highest_role
@property
def feature_flags(self) -> dict[str]:
return self._feature_flags
@property
def server_id(self) -> int:
return self._server_id

View File

@@ -1,100 +0,0 @@
from datetime import datetime
from cpl_core.database import TableABC
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
class ServerTeamRoleIdsConfig(TableABC):
def __init__(
self,
role_id: int,
team_member_type: TeamMemberTypeEnum,
server_id: int,
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._role_id = role_id
self._team_member_type = team_member_type
self._server_id = server_id
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 role_id(self) -> int:
return self._role_id
@property
def team_member_type(self) -> TeamMemberTypeEnum:
return self._team_member_type
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `CFG_ServerTeamRoleIds`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_ServerTeamRoleIds`
WHERE `Id` = {id};
"""
)
@staticmethod
def get_select_by_server_id_string(server_id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_ServerTeamRoleIds`
WHERE `ServerId` = {server_id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `CFG_ServerTeamRoleIds` (
`RoleId`,
`TeamMemberType`,
`ServerId`
) VALUES (
{self._role_id},
'{self._team_member_type.value}',
{self._server_id}
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `CFG_ServerTeamRoleIds`
SET `RoleId` = {self._role_id},
`TeamMemberType` = '{self._team_member_type.value}',
`ServerId` = {self._server_id}
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `CFG_ServerTeamRoleIds`
WHERE `RoleId` = {self._role_id};
"""
)

View File

@@ -1,140 +0,0 @@
from datetime import datetime
from cpl_core.database import TableABC
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC
from bot_data.model.server import Server
from bot_data.model.short_role_name_position_enum import ShortRoleNamePositionEnum
class ShortRoleName(TableABC):
def __init__(
self,
short_name: str,
discord_role_id: int,
position: ShortRoleNamePositionEnum,
server: Server,
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._short_name = short_name
self._discord_role_id = discord_role_id
self._position = position
self._server = server
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 short_name(self) -> str:
return self._short_name
@short_name.setter
def short_name(self, value: str):
self._short_name = value
@property
def role_id(self) -> int:
return self._discord_role_id
@role_id.setter
def role_id(self, value: int):
self._discord_role_id = value
@property
@ServiceProviderABC.inject
def role_name(self, bot: DiscordBotServiceABC) -> str:
guild = bot.get_guild(self._server.discord_id)
return guild.get_role(self.role_id).name
@property
def position(self) -> ShortRoleNamePositionEnum:
return self._position
@position.setter
def position(self, value: ShortRoleNamePositionEnum):
self._position = value
@property
def server(self) -> Server:
return self._server
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `ShortRoleNames`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `ShortRoleNames`
WHERE `Id` = {id};
"""
)
@staticmethod
def get_select_by_role_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `ShortRoleNames`
WHERE `DiscordRoleId` = {id};
"""
)
@staticmethod
def get_select_by_server_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `ShortRoleNames`
WHERE `ServerId` = {id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `ShortRoleNames` (
`ShortName`, `DiscordRoleId`, `Position`, `ServerId`
) VALUES (
'{self._short_name}',
{self._discord_role_id},
'{self._position}',
{self._server.id}
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `ShortRoleNames`
SET `ShortName` = '{self._short_name}',
`DiscordRoleId` = {self._discord_role_id},
`Position` = '{self._position}',
`ServerId` = {self._server.id}
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `ShortRoleNames`
WHERE `Id` = {self._id};
"""
)

View File

@@ -1,56 +0,0 @@
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC
from bot_data.abc.history_table_abc import HistoryTableABC
class ShortRoleNameHistory(HistoryTableABC):
def __init__(
self,
name: str,
discord_role_id: int,
server: int,
deleted: bool,
date_from: str,
date_to: str,
id=0,
):
HistoryTableABC.__init__(self)
self._id = id
self._name = name
self._discord_role_id = discord_role_id
self._server = server
self._deleted = deleted
self._date_from = date_from
self._date_to = date_to
@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 role_id(self) -> int:
return self._discord_role_id
@role_id.setter
def role_id(self, value: int):
self._discord_role_id = value
@property
@ServiceProviderABC.inject
def role_name(self, bot: DiscordBotServiceABC) -> str:
guild = bot.get_guild(self._server.discord_id)
return guild.get_role(self.role_id).name
@property
def server(self) -> int:
return self._server

View File

@@ -1,6 +0,0 @@
from enum import Enum
class ShortRoleNamePositionEnum(Enum):
before = "before"
after = "after"

View File

@@ -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};
"""
)

View File

@@ -1,6 +0,0 @@
from enum import Enum
class TeamMemberTypeEnum(Enum):
moderator = "Moderator"
admin = "Admin"

View File

@@ -1,175 +0,0 @@
import json
from datetime import datetime
from cpl_core.configuration import ConfigurationModelABC
from cpl_core.database import TableABC
from cpl_query.extension import List
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
class TechnicianConfig(TableABC, ConfigurationModelABC):
def __init__(
self,
help_command_reference_url: str,
wait_for_restart: int,
wait_for_shutdown: int,
cache_max_messages: int,
max_steam_offer_count: int,
maintenance: bool,
feature_flags: dict[FeatureFlagsEnum],
technician_ids: List[int],
ping_urls: List[str],
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._help_command_reference_url = help_command_reference_url
self._wait_for_restart = wait_for_restart
self._wait_for_shutdown = wait_for_shutdown
self._cache_max_messages = cache_max_messages
self._max_steam_offer_count = max_steam_offer_count
self._maintenance = maintenance
self._feature_flags = feature_flags
self._technician_ids = technician_ids
self._ping_urls = ping_urls
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 help_command_reference_url(self) -> str:
return self._help_command_reference_url
@help_command_reference_url.setter
def help_command_reference_url(self, value: str):
self._help_command_reference_url = value
@property
def wait_for_restart(self) -> int:
return self._wait_for_restart
@wait_for_restart.setter
def wait_for_restart(self, value: int):
self._wait_for_restart = value
@property
def wait_for_shutdown(self) -> int:
return self._wait_for_shutdown
@wait_for_shutdown.setter
def wait_for_shutdown(self, value: int):
self._wait_for_shutdown = value
@property
def cache_max_messages(self) -> int:
return self._cache_max_messages
@cache_max_messages.setter
def cache_max_messages(self, value: int):
self._cache_max_messages = value
@property
def max_steam_offer_count(self) -> int:
return self._max_steam_offer_count
@max_steam_offer_count.setter
def max_steam_offer_count(self, value: int):
self._max_steam_offer_count = value
@property
def feature_flags(self) -> dict[FeatureFlagsEnum]:
return self._feature_flags
@feature_flags.setter
def feature_flags(self, value: dict[FeatureFlagsEnum]):
self._feature_flags = value
@property
def technician_ids(self) -> List[int]:
return self._technician_ids
@technician_ids.setter
def technician_ids(self, value: List[int]):
self._technician_ids = value
@property
def ping_urls(self) -> List[str]:
return self._ping_urls
@ping_urls.setter
def ping_urls(self, value: List[str]):
self._ping_urls = value
@property
def maintenance(self) -> bool:
return self._maintenance
@maintenance.setter
def maintenance(self, value: bool):
self._maintenance = value
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `CFG_Technician`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_Technician`
WHERE `Id` = {id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `CFG_Technician` (
`HelpCommandReferenceUrl`, `WaitForRestart`, `WaitForShutdown`, `CacheMaxMessages`, `MaxSteamOfferCount`, `FeatureFlags`
) VALUES (
'{self._help_command_reference_url}',
{self._wait_for_restart},
{self._wait_for_shutdown},
{self._cache_max_messages},
{self._max_steam_offer_count},
'{json.dumps(self._feature_flags)}'
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `CFG_Technician`
SET `HelpCommandReferenceUrl` = '{self._help_command_reference_url}',
`WaitForRestart` = {self._wait_for_restart},
`WaitForShutdown` = {self._wait_for_shutdown},
`CacheMaxMessages` = {self._cache_max_messages},
`MaxSteamOfferCount` = {self._max_steam_offer_count},
`FeatureFlags` = '{json.dumps(self._feature_flags)}'
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `CFG_Technician`
WHERE `Id` = {self._id};
"""
)

View File

@@ -1,58 +0,0 @@
from bot_data.abc.history_table_abc import HistoryTableABC
class TechnicianConfigHistory(HistoryTableABC):
def __init__(
self,
help_command_reference_url: str,
wait_for_restart: int,
wait_for_shutdown: int,
cache_max_messages: int,
deleted: bool,
date_from: str,
date_to: str,
id=0,
):
HistoryTableABC.__init__(self)
self._id = id
self._help_command_reference_url = help_command_reference_url
self._wait_for_restart = wait_for_restart
self._wait_for_shutdown = wait_for_shutdown
self._cache_max_messages = cache_max_messages
self._deleted = deleted
self._date_from = date_from
self._date_to = date_to
@property
def help_command_reference_url(self) -> str:
return self._help_command_reference_url
@help_command_reference_url.setter
def help_command_reference_url(self, value: str):
self._help_command_reference_url = value
@property
def wait_for_restart(self) -> int:
return self._wait_for_restart
@wait_for_restart.setter
def wait_for_restart(self, value: int):
self._wait_for_restart = value
@property
def wait_for_shutdown(self) -> int:
return self._wait_for_shutdown
@wait_for_shutdown.setter
def wait_for_shutdown(self, value: int):
self._wait_for_shutdown = value
@property
def cache_max_messages(self) -> int:
return self._cache_max_messages
@cache_max_messages.setter
def cache_max_messages(self, value: int):
self._cache_max_messages = value

View File

@@ -1,79 +0,0 @@
from datetime import datetime
from cpl_core.database import TableABC
class TechnicianIdConfig(TableABC):
def __init__(
self,
technician_id: str,
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._technician_id = technician_id
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 technician_id(self) -> str:
return self._technician_id
@technician_id.setter
def technician_id(self, value: str):
self._technician_id = value
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `CFG_TechnicianIds`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_TechnicianIds`
WHERE `Id` = {id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `CFG_TechnicianIds` (
`TechnicianId`
) VALUES (
'{self._technician_id}'
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `CFG_TechnicianIds`
SET `TechnicianId` = '{self._technician_id}'
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `CFG_TechnicianIds`
WHERE `TechnicianId` = {self._technician_id};
"""
)

View File

@@ -1,28 +0,0 @@
from bot_data.abc.history_table_abc import HistoryTableABC
class TechnicianIdConfigHistory(HistoryTableABC):
def __init__(
self,
technician_id: int,
deleted: bool,
date_from: str,
date_to: str,
id=0,
):
HistoryTableABC.__init__(self)
self._id = id
self._technician_id = technician_id
self._deleted = deleted
self._date_from = date_from
self._date_to = date_to
@property
def technician_id(self) -> int:
return self._technician_id
@technician_id.setter
def technician_id(self, value: int):
self._technician_id = value

View File

@@ -1,79 +0,0 @@
from datetime import datetime
from cpl_core.database import TableABC
class TechnicianPingUrlConfig(TableABC):
def __init__(
self,
ping_url: str,
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._ping_url = ping_url
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 ping_url(self) -> str:
return self._ping_url
@ping_url.setter
def ping_url(self, value: str):
self._ping_url = value
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `CFG_TechnicianPingUrls`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `CFG_TechnicianPingUrls`
WHERE `Id` = {id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `CFG_TechnicianPingUrls` (
`URL`
) VALUES (
'{self._ping_url}'
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `CFG_TechnicianPingUrls`
SET `URL` = '{self._ping_url}'
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `CFG_TechnicianPingUrls`
WHERE `URL` = '{self._ping_url}';
"""
)

View File

@@ -1,28 +0,0 @@
from bot_data.abc.history_table_abc import HistoryTableABC
class TechnicianPingUrlConfigHistory(HistoryTableABC):
def __init__(
self,
url: str,
deleted: bool,
date_from: str,
date_to: str,
id=0,
):
HistoryTableABC.__init__(self)
self._id = id
self._url = url
self._deleted = deleted
self._date_from = date_from
self._date_to = date_to
@property
def url(self) -> str:
return self._url
@url.setter
def url(self, value: str):
self._url = value

View File

@@ -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

View File

@@ -1,152 +0,0 @@
import json
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_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig
from bot_data.model.server_config import ServerConfig
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
class ServerConfigRepositoryService(ServerConfigRepositoryABC):
def __init__(
self,
logger: DatabaseLogger,
db_context: DatabaseContextABC,
servers: ServerRepositoryABC,
):
ServerConfigRepositoryABC.__init__(self)
self._logger = logger
self._context = db_context
self._servers = servers
def _get_team_role_ids(self, server_id: int) -> List[ServerTeamRoleIdsConfig]:
ids = List(ServerTeamRoleIdsConfig)
self._logger.trace(
__name__,
f"Send SQL command: {ServerTeamRoleIdsConfig.get_select_by_server_id_string(server_id)}",
)
results = self._context.select(ServerTeamRoleIdsConfig.get_select_by_server_id_string(server_id))
for result in results:
self._logger.trace(__name__, f"Got ServerTeamRoleIdsConfig with id {result[0]}")
ids.append(
ServerTeamRoleIdsConfig(
result[1],
TeamMemberTypeEnum(result[2]),
result[3],
result[4],
result[5],
id=result[0],
)
)
return ids
def _get_afk_channel_ids(self, server_id: int) -> List[int]:
urls = List(int)
self._logger.trace(
__name__,
f"Send SQL command: {ServerAFKChannelIdsConfig.get_select_by_server_id_string(server_id)}",
)
results = self._context.select(ServerAFKChannelIdsConfig.get_select_by_server_id_string(server_id))
for result in results:
self._logger.trace(__name__, f"Got ServerAFKChannelIdsConfig with id {result[0]}")
urls.append(result[1])
return urls
def _from_result(self, result: tuple) -> ServerConfig:
return ServerConfig(
result[1],
result[2],
result[3],
result[4],
result[5],
result[6],
result[7],
result[8],
result[9],
result[10],
result[11],
result[12],
result[13],
result[14],
result[15],
result[16],
result[17],
json.loads(result[18]),
self._servers.get_server_by_id(result[19]),
self._get_afk_channel_ids(result[19]),
self._get_team_role_ids(result[19]),
result[20],
result[21],
id=result[0],
)
def does_server_config_exists(self, server_id: int) -> bool:
self._logger.trace(
__name__,
f"Send SQL command: {ServerConfig.get_select_by_server_id_string(server_id)}",
)
result = self._context.select(ServerConfig.get_select_by_server_id_string(server_id))
return len(result) > 0
def get_server_config_by_server(self, server_id: int) -> ServerConfig:
self._logger.trace(
__name__,
f"Send SQL command: {ServerConfig.get_select_by_server_id_string(server_id)}",
)
result = self._context.select(ServerConfig.get_select_by_server_id_string(server_id))[0]
return self._from_result(result)
def get_server_config_by_id(self, config_id: int) -> ServerConfig:
self._logger.trace(
__name__,
f"Send SQL command: {ServerConfig.get_select_by_id_string(config_id)}",
)
result = self._context.select(ServerConfig.get_select_by_id_string(config_id))[0]
return self._from_result(result)
def add_server_config(self, server_config: ServerConfig):
self._logger.trace(__name__, f"Send SQL command: {server_config.insert_string}")
self._context.cursor.execute(server_config.insert_string)
def update_server_config(self, server_config: ServerConfig):
self._logger.trace(__name__, f"Send SQL command: {server_config.udpate_string}")
self._context.cursor.execute(server_config.udpate_string)
def delete_server_config(self, server_config: ServerConfig):
self._logger.trace(__name__, f"Send SQL command: {server_config.delete_string}")
self._context.cursor.execute(server_config.delete_string)
def add_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
self._logger.trace(__name__, f"Send SQL command: {server_team_role_id.insert_string}")
self._context.cursor.execute(server_team_role_id.insert_string)
def update_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
self._logger.trace(__name__, f"Send SQL command: {server_team_role_id.udpate_string}")
self._context.cursor.execute(server_team_role_id.udpate_string)
def delete_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
self._logger.trace(__name__, f"Send SQL command: {server_team_role_id.delete_string}")
self._context.cursor.execute(server_team_role_id.delete_string)
def add_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
self._logger.trace(__name__, f"Send SQL command: {server_afk_channel.insert_string}")
self._context.cursor.execute(server_afk_channel.insert_string)
def update_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
self._logger.trace(__name__, f"Send SQL command: {server_afk_channel.udpate_string}")
self._context.cursor.execute(server_afk_channel.udpate_string)
def delete_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
self._logger.trace(__name__, f"Send SQL command: {server_afk_channel.delete_string}")
self._context.cursor.execute(server_afk_channel.delete_string)

View File

@@ -1,45 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.container import Guild
from cpl_discord.service import DiscordBotServiceABC
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.abc.data_seeder_abc import DataSeederABC
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.server_config import ServerConfig
class ServerConfigSeeder(DataSeederABC):
def __init__(
self,
logger: DatabaseLogger,
bot: DiscordBotServiceABC,
servers: ServerRepositoryABC,
server_config: ServerConfigRepositoryABC,
db: DatabaseContextABC,
):
DataSeederABC.__init__(self)
self._logger = logger
self._bot = bot
self._servers = servers
self._server_config = server_config
self._db = db
async def seed(self):
try:
for guild in self._bot.guilds:
guild: Guild = guild
server = self._servers.get_server_by_discord_id(guild.id)
if self._server_config.does_server_config_exists(server.id):
continue
config = ServerConfig.new(guild, server)
self._server_config.add_server_config(config)
self._db.save_changes()
self._logger.debug(__name__, "Seeded server config")
except Exception as e:
self._logger.error(__name__, f"Seeding server config failed", e)

View File

@@ -1,98 +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.short_role_name_repository_abc import ShortRoleNameRepositoryABC
from bot_data.model.short_role_name import ShortRoleName
from bot_data.model.short_role_name_position_enum import ShortRoleNamePositionEnum
class ShortRoleNameRepositoryService(ShortRoleNameRepositoryABC):
def __init__(
self,
logger: DatabaseLogger,
db_context: DatabaseContextABC,
servers: ServerRepositoryABC,
):
self._logger = logger
self._context = db_context
self._servers = servers
ShortRoleNameRepositoryABC.__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 _short_role_name_from_result(self, sql_result: tuple) -> ShortRoleName:
return ShortRoleName(
self._get_value_from_result(sql_result[1]), # name
int(self._get_value_from_result(sql_result[2])), # role_id
ShortRoleNamePositionEnum(self._get_value_from_result(sql_result[3])), # position
self._servers.get_server_by_id(sql_result[4]), # server
self._get_value_from_result(sql_result[5]), # created_at
self._get_value_from_result(sql_result[6]), # modified_at
id=self._get_value_from_result(sql_result[0]), # id
)
def get_short_role_names(self) -> List[ShortRoleName]:
short_role_names = List(ShortRoleName)
self._logger.trace(__name__, f"Send SQL command: {ShortRoleName.get_select_all_string()}")
results = self._context.select(ShortRoleName.get_select_all_string())
for result in results:
self._logger.trace(__name__, f"Get short_role_name with id {result[0]}")
short_role_names.append(self._short_role_name_from_result(result))
return short_role_names
def get_short_role_name_by_id(self, id: int) -> ShortRoleName:
self._logger.trace(__name__, f"Send SQL command: {ShortRoleName.get_select_by_id_string(id)}")
result = self._context.select(ShortRoleName.get_select_by_id_string(id))[0]
return self._short_role_name_from_result(result)
def find_short_role_names_by_role_id(self, role_id: int) -> List[ShortRoleName]:
short_role_names = List(ShortRoleName)
self._logger.trace(
__name__,
f"Send SQL command: {ShortRoleName.get_select_by_role_id_string(role_id)}",
)
results = self._context.select(ShortRoleName.get_select_by_role_id_string(role_id))
for result in results:
self._logger.trace(__name__, f"Get short_role_name with id {result[0]}")
short_role_names.append(self._short_role_name_from_result(result))
return short_role_names
def get_short_role_names_by_server_id(self, server_id: int) -> List[ShortRoleName]:
short_role_names = List(ShortRoleName)
self._logger.trace(
__name__,
f"Send SQL command: {ShortRoleName.get_select_by_server_id_string(server_id)}",
)
results = self._context.select(ShortRoleName.get_select_by_server_id_string(server_id))
for result in results:
self._logger.trace(__name__, f"Get short_role_name with id {result[0]}")
short_role_names.append(self._short_role_name_from_result(result))
return short_role_names
def add_short_role_name(self, short_role_name: ShortRoleName):
self._logger.trace(__name__, f"Send SQL command: {short_role_name.insert_string}")
self._context.cursor.execute(short_role_name.insert_string)
def update_short_role_name(self, short_role_name: ShortRoleName):
self._logger.trace(__name__, f"Send SQL command: {short_role_name.udpate_string}")
self._context.cursor.execute(short_role_name.udpate_string)
def delete_short_role_name(self, short_role_name: ShortRoleName):
self._logger.trace(__name__, f"Send SQL command: {short_role_name.delete_string}")
self._context.cursor.execute(short_role_name.delete_string)

View File

@@ -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)

View File

@@ -1,105 +0,0 @@
import json
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.technician_config_repository_abc import TechnicianConfigRepositoryABC
from bot_data.model.technician_config import TechnicianConfig
from bot_data.model.technician_id_config import TechnicianIdConfig
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
class TechnicianConfigRepositoryService(TechnicianConfigRepositoryABC):
def __init__(self, logger: DatabaseLogger, db_context: DatabaseContextABC):
TechnicianConfigRepositoryABC.__init__(self)
self._logger = logger
self._context = db_context
def _get_technician_ids(self) -> List[int]:
ids = List(int)
self._logger.trace(__name__, f"Send SQL command: {TechnicianIdConfig.get_select_all_string()}")
results = self._context.select(TechnicianIdConfig.get_select_all_string())
for result in results:
self._logger.trace(__name__, f"Got TechnicianId with id {result[0]}")
ids.append(result[1])
return ids
def _get_technician_ping_urls(self) -> List[str]:
urls = List(str)
self._logger.trace(
__name__,
f"Send SQL command: {TechnicianPingUrlConfig.get_select_all_string()}",
)
results = self._context.select(TechnicianPingUrlConfig.get_select_all_string())
for result in results:
self._logger.trace(__name__, f"Got TechnicianPingUrl with id {result[0]}")
urls.append(result[1])
return urls
def _from_result(self, result: tuple) -> TechnicianConfig:
return TechnicianConfig(
result[1],
result[2],
result[3],
result[4],
result[5],
bool(result[6]),
json.loads(result[7]),
self._get_technician_ids(),
self._get_technician_ping_urls(),
result[8],
result[9],
id=result[0],
)
def does_technician_config_exists(self) -> bool:
self._logger.trace(__name__, f"Send SQL command: {TechnicianConfig.get_select_all_string()}")
result = self._context.select(TechnicianConfig.get_select_all_string())
return len(result) > 0
def get_technician_config(self) -> TechnicianConfig:
self._logger.trace(__name__, f"Send SQL command: {TechnicianConfig.get_select_all_string()}")
result = self._context.select(TechnicianConfig.get_select_all_string())[0]
return self._from_result(result)
def add_technician_config(self, technician_config: TechnicianConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_config.insert_string}")
self._context.cursor.execute(technician_config.insert_string)
def update_technician_config(self, technician_config: TechnicianConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_config.udpate_string}")
self._context.cursor.execute(technician_config.udpate_string)
def delete_technician_config(self, technician_config: TechnicianConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_config.delete_string}")
self._context.cursor.execute(technician_config.delete_string)
def add_technician_id_config(self, technician_id: TechnicianIdConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_id.insert_string}")
self._context.cursor.execute(technician_id.insert_string)
def update_technician_id_config(self, technician_id: TechnicianIdConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_id.udpate_string}")
self._context.cursor.execute(technician_id.udpate_string)
def delete_technician_id_config(self, technician_id: TechnicianIdConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_id.delete_string}")
self._context.cursor.execute(technician_id.delete_string)
def add_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_ping_url.insert_string}")
self._context.cursor.execute(technician_ping_url.insert_string)
def update_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_ping_url.udpate_string}")
self._context.cursor.execute(technician_ping_url.udpate_string)
def delete_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
self._logger.trace(__name__, f"Send SQL command: {technician_ping_url.delete_string}")
self._context.cursor.execute(technician_ping_url.delete_string)

View File

@@ -1,53 +0,0 @@
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.data_seeder_abc import DataSeederABC
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
from bot_data.model.technician_config import TechnicianConfig
from bot_data.model.technician_id_config import TechnicianIdConfig
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
class TechnicianConfigSeeder(DataSeederABC):
def __init__(
self,
logger: DatabaseLogger,
technician_config: TechnicianConfigRepositoryABC,
db: DatabaseContextABC,
):
DataSeederABC.__init__(self)
self._logger = logger
self._technician_config = technician_config
self._db = db
async def seed(self):
try:
if self._technician_config.does_technician_config_exists():
return
config = TechnicianConfig(
"https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot/wiki/Befehle",
8,
8,
1000000,
{},
List(int, [240160344557879316]),
List(
str,
["www.google.com", "www.sh-edraft.de", "www.keksdose-gaming.de"],
),
)
self._technician_config.add_technician_config(config)
for technician in config.technician_ids:
self._technician_config.add_technician_id_config(TechnicianIdConfig(technician))
for url in config.ping_urls:
self._technician_config.add_technician_ping_url_config(TechnicianPingUrlConfig(url))
self._db.save_changes()
self._logger.debug(__name__, "Seeded technician config")
except Exception as e:
self._logger.error(__name__, f"Seeding technician config failed", e)

View File

@@ -1,70 +0,0 @@
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from bot_data.model.short_role_name import ShortRoleName
from bot_data.model.short_role_name_position_enum import ShortRoleNamePositionEnum
from bot_data.model.user import User
from bot_graphql.abc.filter_abc import FilterABC
class ShortRoleNameFilter(FilterABC):
def __init__(self, bot: DiscordBotServiceABC):
FilterABC.__init__(self)
self._bot = bot
self._id = None
self._short_name = None
self._role_id = None
self._role_name = None
self._position = None
self._server = None
def from_dict(self, values: dict):
if "id" in values:
self._id = int(values["id"])
if "shortName" in values:
self._short_name = values["shortName"]
if "roleId" in values:
self._role_id = int(values["roleId"])
if "roleName" in values:
self._role_name = values["roleName"]
if "position" in values:
self._position = ShortRoleNamePositionEnum(values["position"])
if "server" in values:
from bot_graphql.filter.server_filter import ServerFilter
self._server: ServerFilter = self._services.get_service(ServerFilter)
self._server.from_dict(values["server"])
def filter(self, query: List[User]) -> List[User]:
if self._id is not None:
query = query.where(lambda x: x.id == self._id)
if self._short_name is not None:
query = query.where(lambda x: x.short_name == self._short_name or self._short_name in x.short_name)
if self._role_id is not None:
query = query.where(lambda x: x.role_id == self._role_id)
if self._role_name is not None and self._role_id is not None:
def get_role_name(x: ShortRoleName):
guild = self._bot.get_guild(x.server.discord_id)
name = guild.get_role(x.role_id).name
return name == self._role_name or self._role_name in name
query = query.where(get_role_name)
if self._position is not None:
query = query.where(lambda x: x.position.value == self._position.value)
if self._server is not None:
servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id)
query = query.where(lambda x: x.server.id in servers)
return query

View File

@@ -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

View File

@@ -1,53 +0,0 @@
type Discord {
guilds(filter: GuildFilter): [Guild]
users(filter: DiscordUserFilter): [DiscordUser]
}
type Guild {
id: ID
name: String
channels(filter: ChannelFilter): [Channel]
roles: [Role]
emojis: [Emoji]
}
input GuildFilter {
id: ID
name: String
}
type Channel {
id: String
name: String
type: String
}
input ChannelFilter {
id: String
name: String
type: String
}
type Role {
id: String
name: String
}
type DiscordUser {
id: String
name: String
bot: Boolean
}
input DiscordUserFilter {
id: ID
name: String
bot: Boolean
}
type Emoji {
id: String
name: String
url: String
}

View File

@@ -1,9 +0,0 @@
type FeatureFlag {
key: String
value: Boolean
}
input FeatureFlagInput {
key: String
value: Boolean
}

View File

@@ -1,111 +0,0 @@
type ServerConfig implements TableWithHistoryQuery {
id: ID
messageDeleteTimer: Int
notificationChatId: String
maxVoiceStateHours: Int
xpPerMessage: Int
xpPerReaction: Int
maxMessageXpPerHour: Int
xpPerOntimeHour: Int
xpPerEventParticipation: Int
xpPerAchievement: Int
xpForBirthday: Int
afkCommandChannelId: String
helpVoiceChannelId: String
teamChannelId: String
loginMessageChannelId: String
defaultRoleId: String
shortRoleNameOnlySetHighestRole: Boolean
gameOfferNotificationChatId: String
featureFlagCount: Int
featureFlags: [FeatureFlag]
afkChannelIds: [String]
moderatorRoleIds: [String]
adminRoleIds: [String]
server: Server
createdAt: String
modifiedAt: String
history: [ServerConfigHistory]
}
type ServerConfigHistory implements HistoryTableQuery {
id: ID
messageDeleteTimer: Int
notificationChatId: String
maxVoiceStateHours: Int
xpPerMessage: Int
xpPerReaction: Int
maxMessageXpPerHour: Int
xpPerOntimeHour: Int
xpPerEventParticipation: Int
xpPerAchievement: Int
xpForBirthday: Int
afkCommandChannelId: String
helpVoiceChannelId: String
teamChannelId: String
loginMessageChannelId: String
defaultRoleId: String
shortRoleNameOnlySetHighestRole: Boolean
gameOfferNotificationChatId: String
featureFlagCount: Int
featureFlags: [FeatureFlag]
serverId: ID
deleted: Boolean
dateFrom: String
dateTo: String
}
type ServerAFKChannelIdsConfigHistory implements HistoryTableQuery {
id: ID
channelId: String
deleted: Boolean
dateFrom: String
dateTo: String
}
type ServerTeamRoleIdsConfigHistory implements HistoryTableQuery {
id: ID
roleId: String
teamMemberType: String
deleted: Boolean
dateFrom: String
dateTo: String
}
type ServerConfigMutation {
updateServerConfig(input: ServerConfigInput!): ServerConfig
}
input ServerConfigInput {
id: ID
messageDeleteTimer: Int
notificationChatId: String
maxVoiceStateHours: Int
xpPerMessage: Int
xpPerReaction: Int
maxMessageXpPerHour: Int
xpPerOntimeHour: Int
xpPerEventParticipation: Int
xpPerAchievement: Int
xpForBirthday: Int
afkCommandChannelId: String
helpVoiceChannelId: String
teamChannelId: String
loginMessageChannelId: String
defaultRoleId: String
shortRoleNameOnlySetHighestRole: Boolean
gameOfferNotificationChatId: String
featureFlags: [FeatureFlagInput]
afkChannelIds: [String]
moderatorRoleIds: [String]
adminRoleIds: [String]
}

View File

@@ -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
}

View File

@@ -1,50 +0,0 @@
type ShortRoleName implements TableWithHistoryQuery {
id: ID
shortName: String
roleId: String
roleName: String
position: String
server: Server
createdAt: String
modifiedAt: String
history: [ShortRoleNameHistory]
}
type ShortRoleNameHistory implements HistoryTableQuery {
id: ID
shortName: String
roleId: String
position: String
server: ID
deleted: Boolean
dateFrom: String
dateTo: String
}
input ShortRoleNameFilter {
id: ID
shortName: String
roleId: String
roleName: String
position: String
}
type ShortRoleNameMutation {
createShortRoleName(input: ShortRoleNameInput!): ShortRoleName
updateShortRoleName(input: ShortRoleNameInput!): ShortRoleName
deleteShortRoleName(id: ID): ShortRoleName
}
input ShortRoleNameInput {
id: ID
shortName: String
roleId: String
roleName: String
position: String
serverId: ID
}

View File

@@ -1,71 +0,0 @@
type TechnicianConfig implements TableWithHistoryQuery {
id: ID
helpCommandReferenceUrl: String
waitForRestart: Int
waitForShutdown: Int
cacheMaxMessages: Int
maxSteamOfferCount: Int
maintenance: Boolean
featureFlagCount: Int
featureFlags: [FeatureFlag]
pingURLs: [String]
technicianIds: [String]
createdAt: String
modifiedAt: String
history: [TechnicianConfigHistory]
pingURLHistory: [TechnicianPingUrlConfigHistory]
technicianIdHistory: [TechnicianIdConfigHistory]
}
type TechnicianConfigHistory implements HistoryTableQuery {
id: ID
helpCommandReferenceUrl: String
waitForRestart: Int
waitForShutdown: Int
cacheMaxMessages: Int
maxSteamOfferCount: Int
maintenance: Boolean
featureFlagCount: Int
featureFlags: [FeatureFlag]
deleted: Boolean
dateFrom: String
dateTo: String
}
type TechnicianPingUrlConfigHistory implements HistoryTableQuery {
id: ID
url: String
deleted: Boolean
dateFrom: String
dateTo: String
}
type TechnicianIdConfigHistory implements HistoryTableQuery {
id: ID
technicianId: String
deleted: Boolean
dateFrom: String
dateTo: String
}
type TechnicianConfigMutation {
updateTechnicianConfig(input: TechnicianConfigInput!): TechnicianConfig
}
input TechnicianConfigInput {
id: ID
helpCommandReferenceUrl: String
waitForRestart: Int
waitForShutdown: Int
cacheMaxMessages: Int
maxSteamOfferCount: Int
maintenance: Boolean
featureFlags: [FeatureFlagInput]
pingURLs: [String]
technicianIds: [String]
}

View File

@@ -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
}

View File

@@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
bot sh-edraft.de Discord bot
~~~~~~~~~~~~~~~~~~~
Discord bot for customers of sh-edraft.de
:copyright: (c) 2022 - 2023 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = "bot_graphql.model"
__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")

View File

@@ -1,16 +0,0 @@
from cpl_query.extension import List
from discord import Guild, User
class Discord:
def __init__(self, guilds: List[Guild], users: List[User]):
self._guilds = guilds
self._users = users
@property
def guilds(self) -> List[Guild]:
return self._guilds
@property
def users(self) -> List[User]:
return self._users

View File

@@ -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

View File

@@ -1,194 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from bot_api.logging.api_logger import ApiLogger
from bot_api.route.route import Route
from bot_core.service.config_service import ConfigService
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig
from bot_data.model.server_config import ServerConfig
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
from bot_data.model.user_role_enum import UserRoleEnum
from bot_graphql.abc.query_abc import QueryABC
class ServerConfigMutation(QueryABC):
def __init__(
self,
logger: ApiLogger,
bot: DiscordBotServiceABC,
servers: ServerRepositoryABC,
server_configs: ServerConfigRepositoryABC,
db: DatabaseContextABC,
config_service: ConfigService,
):
QueryABC.__init__(self, "ServerConfigMutation")
self._logger = logger
self._bot = bot
self._servers = servers
self._server_configs = server_configs
self._db = db
self._config_service = config_service
self.set_field("updateServerConfig", self.resolve_update_server_config)
def resolve_update_server_config(self, *_, input: dict):
if "id" not in input:
raise ValueError("Id not set")
server_config = self._server_configs.get_server_config_by_id(int(input["id"]))
self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician)
server_config.message_delete_timer = (
input["messageDeleteTimer"] if "messageDeleteTimer" in input else server_config.message_delete_timer
)
server_config.notification_chat_id = (
input["notificationChatId"] if "notificationChatId" in input else server_config.notification_chat_id
)
server_config.max_voice_state_hours = (
input["maxVoiceStateHours"] if "maxVoiceStateHours" in input else server_config.max_voice_state_hours
)
server_config.xp_per_message = (
input["xpPerMessage"] if "xpPerMessage" in input else server_config.xp_per_message
)
server_config.xp_per_reaction = (
input["xpPerReaction"] if "xpPerReaction" in input else server_config.xp_per_reaction
)
server_config.max_message_xp_per_hour = (
input["maxMessageXpPerHour"] if "maxMessageXpPerHour" in input else server_config.max_message_xp_per_hour
)
server_config.xp_per_ontime_hour = (
input["xpPerOntimeHour"] if "xpPerOntimeHour" in input else server_config.xp_per_ontime_hour
)
server_config.xp_per_event_participation = (
input["xpPerEventParticipation"]
if "xpPerEventParticipation" in input
else server_config.xp_per_event_participation
)
server_config.xp_per_achievement = (
input["xpPerAchievement"] if "xpPerAchievement" in input else server_config.xp_per_achievement
)
server_config.xp_for_birthday = (
input["xpForBirthday"] if "xpForBirthday" in input else server_config.xp_for_birthday
)
server_config.afk_command_channel_id = (
input["afkCommandChannelId"] if "afkCommandChannelId" in input else server_config.afk_command_channel_id
)
server_config.help_voice_channel_id = (
input["helpVoiceChannelId"] if "helpVoiceChannelId" in input else server_config.help_voice_channel_id
)
server_config.team_channel_id = (
input["teamChannelId"] if "teamChannelId" in input else server_config.team_channel_id
)
server_config.login_message_channel_id = (
input["loginMessageChannelId"]
if "loginMessageChannelId" in input
else server_config.login_message_channel_id
)
server_config.default_role_id = (
input["defaultRoleId"] if "defaultRoleId" in input else server_config.default_role_id
)
server_config.short_role_name_only_set_highest_role = (
input["shortRoleNameOnlySetHighestRole"]
if "shortRoleNameOnlySetHighestRole" in input
else server_config.short_role_name_only_set_highest_role
)
server_config.game_offer_notification_chat_id = (
input["gameOfferNotificationChatId"]
if "gameOfferNotificationChatId" in input
else server_config.game_offer_notification_chat_id
)
server_config.feature_flags = (
dict(
zip(
[x["key"] for x in input["featureFlags"]],
[x["value"] for x in input["featureFlags"]],
)
)
if "featureFlags" in input
else server_config.feature_flags
)
server_config.afk_channel_ids = (
List(int).extend([int(x) for x in input["afkChannelIds"]])
if "afkChannelIds" in input
else server_config.afk_channel_ids
)
team_role_ids = List(ServerTeamRoleIdsConfig)
if "moderatorRoleIds" in input:
team_role_ids.extend(
[
ServerTeamRoleIdsConfig(x, TeamMemberTypeEnum.moderator, server_config.server.id)
for x in input["moderatorRoleIds"]
]
)
else:
team_role_ids.extend(
server_config.team_role_ids.where(lambda x: x.team_member_type == TeamMemberTypeEnum.moderator)
)
if "adminRoleIds" in input:
team_role_ids.extend(
[
ServerTeamRoleIdsConfig(x, TeamMemberTypeEnum.admin, server_config.server.id)
for x in input["adminRoleIds"]
]
)
else:
team_role_ids.extend(
server_config.team_role_ids.where(lambda x: x.team_member_type == TeamMemberTypeEnum.admin)
)
self._server_configs.update_server_config(server_config)
if "afkChannelIds" in input:
self._update_afk_channel_ids(server_config)
if "moderatorRoleIds" in input or "adminRoleIds" in input:
server_config.team_role_ids = team_role_ids
self._update_team_role_ids(server_config)
self._db.save_changes()
self._bot.loop.create_task(self._config_service.reload_server_config(server_config.server))
return server_config
def _update_afk_channel_ids(self, new_config: ServerConfig):
old_config = self._server_configs.get_server_config_by_server(new_config.server.id)
for channel_id in old_config.afk_channel_ids:
if channel_id in new_config.afk_channel_ids:
continue
self._server_configs.delete_server_afk_channel_config(
ServerAFKChannelIdsConfig(channel_id, new_config.server.id)
)
for channel_id in new_config.afk_channel_ids:
if channel_id in old_config.afk_channel_ids:
continue
self._server_configs.add_server_afk_channel_config(
ServerAFKChannelIdsConfig(channel_id, new_config.server.id)
)
def _update_team_role_ids(self, new_config: ServerConfig):
old_config = self._server_configs.get_server_config_by_server(new_config.server.id)
for role_id in old_config.team_role_ids:
if role_id.role_id in new_config.team_role_ids.select(lambda x: int(x.role_id)):
continue
self._server_configs.delete_server_team_role_id_config(role_id)
for role_id in new_config.team_role_ids:
guild = self._bot.get_guild(new_config.server.discord_id)
role = guild.get_role(int(role_id.role_id))
if role is None:
raise ValueError(f"Invalid roleId")
for role_id in new_config.team_role_ids:
if role_id.role_id in old_config.team_role_ids.select(lambda x: str(x.role_id)):
continue
self._server_configs.add_server_team_role_id_config(role_id)

View File

@@ -1,85 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
from bot_data.model.short_role_name import ShortRoleName
from bot_data.model.user_role_enum import UserRoleEnum
from bot_graphql.abc.query_abc import QueryABC
from modules.permission.service.permission_service import PermissionService
class ShortRoleNameMutation(QueryABC):
def __init__(
self,
servers: ServerRepositoryABC,
short_role_names: ShortRoleNameRepositoryABC,
bot: DiscordBotServiceABC,
db: DatabaseContextABC,
permissions: PermissionService,
):
QueryABC.__init__(self, "ShortRoleNameMutation")
self._servers = servers
self._short_role_names = short_role_names
self._bot = bot
self._db = db
self._permissions = permissions
self.set_field("createShortRoleName", self.resolve_create_short_role_name)
self.set_field("updateShortRoleName", self.resolve_update_short_role_name)
self.set_field("deleteShortRoleName", self.resolve_delete_short_role_name)
def resolve_create_short_role_name(self, *_, input: dict):
server = self._servers.get_server_by_id(input["serverId"])
self._can_user_mutate_data(server, UserRoleEnum.admin)
short_role_name = ShortRoleName(
input["shortName"],
int(input["roleId"]),
input["position"],
server,
)
result = self._short_role_names.find_short_role_names_by_role_id(short_role_name.role_id)
if result.count() > 0:
raise ValueError("Short name for role already exists")
self._short_role_names.add_short_role_name(short_role_name)
self._db.save_changes()
def get_new_short_role_name(srn: ShortRoleName):
return (
srn.short_name == short_role_name.short_name
and srn.role_id == short_role_name.role_id
and srn.position.value == short_role_name.position
)
return (
self._short_role_names.get_short_role_names_by_server_id(short_role_name.server.id)
.where(get_new_short_role_name)
.last()
)
def resolve_update_short_role_name(self, *_, input: dict):
short_role_name = self._short_role_names.get_short_role_name_by_id(input["id"])
self._can_user_mutate_data(short_role_name.server, UserRoleEnum.moderator)
short_role_name.short_name = input["shortName"] if "shortName" in input else short_role_name.short_name
short_role_name.role_id = input["roleId"] if "roleId" in input else short_role_name.role_id
short_role_name.position = input["position"] if "position" in input else short_role_name.position
self._short_role_names.update_short_role_name(short_role_name)
self._db.save_changes()
short_role_name = self._short_role_names.get_short_role_name_by_id(input["id"])
return short_role_name
def resolve_delete_short_role_name(self, *_, id: int):
short_role_name = self._short_role_names.get_short_role_name_by_id(id)
self._can_user_mutate_data(short_role_name.server, UserRoleEnum.admin)
self._short_role_names.delete_short_role_name(short_role_name)
self._db.save_changes()
return short_role_name

View File

@@ -1,144 +0,0 @@
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 bot_api.logging.api_logger import ApiLogger
from bot_api.route.route import Route
from bot_core.abc.client_utils_abc import ClientUtilsABC
from bot_core.environment_variables import MAINTENANCE
from bot_core.service.config_service import ConfigService
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
from bot_data.model.technician_config import TechnicianConfig
from bot_data.model.technician_id_config import TechnicianIdConfig
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
from bot_data.model.user_role_enum import UserRoleEnum
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
from bot_graphql.abc.query_abc import QueryABC
class TechnicianConfigMutation(QueryABC):
def __init__(
self,
config: ConfigurationABC,
logger: ApiLogger,
bot: DiscordBotServiceABC,
servers: ServerRepositoryABC,
technician_configs: TechnicianConfigRepositoryABC,
db: DatabaseContextABC,
config_service: ConfigService,
tech_seeder: TechnicianConfigSeeder,
client_utils: ClientUtilsABC,
):
QueryABC.__init__(self, "TechnicianConfigMutation")
self._config = config
self._logger = logger
self._bot = bot
self._servers = servers
self._technician_configs = technician_configs
self._db = db
self._config_service = config_service
self._tech_seeder = tech_seeder
self._client_utils = client_utils
self.set_field("updateTechnicianConfig", self.resolve_update_technician_config)
def resolve_update_technician_config(self, *_, input: dict):
if not self._technician_configs.does_technician_config_exists():
self._bot.loop.create_task(self._tech_seeder.seed())
technician_config = self._technician_configs.get_technician_config()
self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician)
technician_config.help_command_reference_url = (
input["helpCommandReferenceUrl"]
if "helpCommandReferenceUrl" in input
else technician_config.help_command_reference_url
)
technician_config.wait_for_restart = (
input["waitForRestart"] if "waitForRestart" in input else technician_config.wait_for_restart
)
technician_config.wait_for_shutdown = (
input["waitForShutdown"] if "waitForShutdown" in input else technician_config.wait_for_shutdown
)
technician_config.cache_max_messages = (
input["cacheMaxMessages"] if "cacheMaxMessages" in input else technician_config.cache_max_messages
)
technician_config.max_steam_offer_count = (
input["maxSteamOfferCount"] if "maxSteamOfferCount" in input else technician_config.max_steam_offer_count
)
technician_config.maintenance = (
input["maintenance"] if "maintenance" in input else technician_config.maintenance
)
old_feature_flags = technician_config.feature_flags
technician_config.feature_flags = (
dict(
zip(
[x["key"] for x in input["featureFlags"]],
[x["value"] for x in input["featureFlags"]],
)
)
if "featureFlags" in input
else technician_config.feature_flags
)
for old_flag in old_feature_flags:
if old_flag not in technician_config.feature_flags:
technician_config.feature_flags[old_flag] = False
technician_config.ping_urls = (
List(str, input["pingURLs"]) if "pingURLs" in input else technician_config.ping_urls
)
technician_config.technician_ids = (
List(int).extend([int(x) for x in input["technicianIds"]])
if "technicianIds" in input
else technician_config.technician_ids
)
self._technician_configs.update_technician_config(technician_config)
if "pingURLs" in input:
self._update_ping_urls(technician_config)
if "technicianIds" in input:
self._update_technician_ids(technician_config)
self._db.save_changes()
if technician_config.maintenance != self._config.get_configuration(MAINTENANCE):
self._bot.loop.create_task(self._client_utils.set_maintenance_mode(technician_config.maintenance))
self._bot.loop.create_task(self._config_service.reload_technician_config())
return technician_config
def _update_ping_urls(self, new_config: TechnicianConfig):
old_config = self._technician_configs.get_technician_config()
for url in old_config.ping_urls:
if url in new_config.ping_urls:
continue
self._technician_configs.delete_technician_ping_url_config(TechnicianPingUrlConfig(url))
for url in new_config.ping_urls:
if url in old_config.ping_urls:
continue
self._technician_configs.add_technician_ping_url_config(TechnicianPingUrlConfig(url))
def _update_technician_ids(self, new_config: TechnicianConfig):
old_config = self._technician_configs.get_technician_config()
for technician_id in old_config.technician_ids:
if technician_id in new_config.technician_ids:
continue
self._technician_configs.delete_technician_id_config(TechnicianIdConfig(technician_id))
for technician_id in new_config.technician_ids:
user = self._bot.get_user(technician_id)
if user is None:
raise ValueError(f"Invalid technicianId")
for technician_id in new_config.technician_ids:
if technician_id in old_config.technician_ids:
continue
self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id))

View File

@@ -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)

View File

@@ -1,10 +0,0 @@
from bot_graphql.abc.query_abc import QueryABC
class ChannelQuery(QueryABC):
def __init__(self):
QueryABC.__init__(self, "Channel")
self.set_field("id", lambda c, *_: c.id)
self.set_field("name", lambda c, *_: c.name)
self.set_field("type", lambda c, *_: type(c).__name__)

View File

@@ -1,48 +0,0 @@
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from bot_graphql.abc.query_abc import QueryABC
class DiscordQuery(QueryABC):
def __init__(
self,
bot: DiscordBotServiceABC,
):
QueryABC.__init__(self, "Discord")
self._bot = bot
self.set_field("guilds", self._resolve_guilds)
self.set_field("users", self._resolve_users)
def _resolve_guilds(self, *_, filter=None):
guilds = self._bot.guilds
if filter is None:
return guilds
if "id" in filter:
guilds = self._bot.guilds.where(lambda g: g.id == int(filter["id"]))
if "name" in filter:
guilds = self._bot.guilds.where(lambda g: g.name == filter["name"])
return guilds
def _resolve_users(self, *_, filter=None):
users = List(any).extend(self._bot.users)
if filter is None:
return users
if "id" in filter:
users = users.where(lambda g: g.id == int(filter["id"]))
if "name" in filter:
users = users.where(lambda g: g.name == filter["name"])
if "bot" in filter:
users = users.where(lambda g: g.bot == bool(filter["bot"]))
return users

View File

@@ -1,10 +0,0 @@
from bot_graphql.abc.query_abc import QueryABC
class DiscordUserQuery(QueryABC):
def __init__(self):
QueryABC.__init__(self, "DiscordUser")
self.set_field("id", lambda r, *_: r.id)
self.set_field("name", lambda r, *_: r.name)
self.set_field("bot", lambda r, *_: r.bot)

View File

@@ -1,42 +0,0 @@
import discord
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from discord import Guild
from bot_graphql.abc.query_abc import QueryABC
class GuildQuery(QueryABC):
def __init__(
self,
bot: DiscordBotServiceABC,
):
QueryABC.__init__(self, "Guild")
self._bot = bot
self.set_field("id", lambda g, *_: g.id)
self.set_field("name", lambda g, *_: g.name)
self.set_field("channels", self._resolve_channels)
self.set_field("roles", lambda g, *_: g.roles.order_by(lambda x: x.position))
self.set_field(
"emojis",
lambda g, *_: List(discord.Emoji, g.emojis).order_by_descending(lambda x: x.created_at),
)
def _resolve_channels(self, g: Guild, *_, filter=None):
channels = List(any).extend(g.channels).order_by(lambda x: x.position)
if filter is None:
return channels
if "id" in filter:
channels = channels.where(lambda c: c.id == int(filter["id"]))
if "name" in filter:
channels = channels.where(lambda c: c.id == filter["name"])
if "type" in filter:
channels = channels.where(lambda c: type(c).__name__ == filter["type"])
return channels

View File

@@ -1,9 +0,0 @@
from bot_graphql.abc.query_abc import QueryABC
class RoleQuery(QueryABC):
def __init__(self):
QueryABC.__init__(self, "Role")
self.set_field("id", lambda r, *_: r.id)
self.set_field("name", lambda r, *_: r.name)

View File

@@ -1,60 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from cpl_query.extension import List
from bot_data.model.server_config_history import ServerConfigHistory
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class ServerConfigQuery(DataQueryWithHistoryABC):
def __init__(self, db: DatabaseContextABC):
DataQueryWithHistoryABC.__init__(self, "ServerConfig", "CFG_ServerHistory", ServerConfigHistory, db)
self.set_field("id", lambda config, *_: config.id)
self.set_field("messageDeleteTimer", lambda config, *_: config.message_delete_timer)
self.set_field("notificationChatId", lambda config, *_: config.notification_chat_id)
self.set_field("maxVoiceStateHours", lambda config, *_: config.max_voice_state_hours)
self.set_field("xpPerMessage", lambda config, *_: config.xp_per_message)
self.set_field("xpPerReaction", lambda config, *_: config.xp_per_reaction)
self.set_field("maxMessageXpPerHour", lambda config, *_: config.max_message_xp_per_hour)
self.set_field("xpPerOntimeHour", lambda config, *_: config.xp_per_ontime_hour)
self.set_field(
"xpPerEventParticipation",
lambda config, *_: config.xp_per_event_participation,
)
self.set_field("xpPerAchievement", lambda config, *_: config.xp_per_achievement)
self.set_field("xpForBirthday", lambda config, *_: config.xp_for_birthday)
self.set_field("afkCommandChannelId", lambda config, *_: config.afk_command_channel_id)
self.set_field("helpVoiceChannelId", lambda config, *_: config.help_voice_channel_id)
self.set_field("teamChannelId", lambda config, *_: config.team_channel_id)
self.set_field("loginMessageChannelId", lambda config, *_: config.login_message_channel_id)
self.set_field("defaultRoleId", lambda config, *_: config.default_role_id)
self.set_field(
"shortRoleNameOnlySetHighestRole",
lambda config, *_: config.short_role_name_only_set_highest_role,
)
self.set_field(
"gameOfferNotificationChatId",
lambda config, *_: config.game_offer_notification_chat_id,
)
self.add_collection(
"featureFlag",
lambda config, *_: List(
any,
[{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags],
),
)
self.set_field("afkChannelIds", lambda config, *_: config.afk_channel_ids)
self.set_field(
"moderatorRoleIds",
lambda config, *_: config.team_role_ids.where(
lambda x: x.team_member_type == TeamMemberTypeEnum.moderator
).select(lambda x: x.role_id),
)
self.set_field(
"adminRoleIds",
lambda config, *_: config.team_role_ids.where(
lambda x: x.team_member_type == TeamMemberTypeEnum.admin
).select(lambda x: x.role_id),
)
self.set_field("server", lambda config, *_: config.server)

View File

@@ -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()

View File

@@ -1,11 +0,0 @@
from bot_graphql.abc.history_query_abc import HistoryQueryABC
class ShortRoleNameHistoryQuery(HistoryQueryABC):
def __init__(self):
HistoryQueryABC.__init__(self, "ShortRoleName")
self.set_field("id", lambda x, *_: x.id)
self.set_field("shortName", lambda x, *_: x.shortName)
self.set_field("roleId", lambda x, *_: x.roleId)
self.set_field("position", lambda x, *_: x.position.value)

View File

@@ -1,18 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from bot_data.model.short_role_name_history import ShortRoleNameHistory
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class ShortRoleNameQuery(DataQueryWithHistoryABC):
def __init__(
self,
db: DatabaseContextABC,
):
DataQueryWithHistoryABC.__init__(self, "ShortRoleName", "ShortRoleNamesHistory", ShortRoleNameHistory, db)
self.set_field("id", lambda x, *_: x.id)
self.set_field("shortName", lambda x, *_: x.short_name)
self.set_field("roleId", lambda x, *_: x.role_id)
self.set_field("roleName", lambda x, *_: x.role_name)
self.set_field("position", lambda x, *_: x.position.value)

View File

@@ -1,25 +0,0 @@
from cpl_query.extension import List
from bot_graphql.abc.history_query_abc import HistoryQueryABC
class TechnicianConfigHistoryQuery(HistoryQueryABC):
def __init__(self):
HistoryQueryABC.__init__(self, "TechnicianConfig")
self.set_field(
"helpCommandReferenceUrl",
lambda config, *_: config.help_command_reference_url,
)
self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart)
self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown)
self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages)
self.set_field("maxSteamOfferCount", lambda config, *_: config.max_steam_offer_count)
self.set_field("maintenance", lambda config, *_: config.maintenance)
self.add_collection(
"featureFlag",
lambda config, *_: List(
any,
[{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags],
),
)

View File

@@ -1,77 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from cpl_query.extension import List
from bot_data.abc.table_with_id_abc import TableWithIdABC
from bot_data.model.technician_config_history import TechnicianConfigHistory
from bot_data.model.technician_id_config_history import TechnicianIdConfigHistory
from bot_data.model.technician_ping_url_config_history import (
TechnicianPingUrlConfigHistory,
)
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class TechnicianConfigQuery(DataQueryWithHistoryABC):
def __init__(self, db: DatabaseContextABC):
DataQueryWithHistoryABC.__init__(
self,
"TechnicianConfig",
"CFG_TechnicianHistory",
TechnicianConfigHistory,
db,
)
self.set_field(
"helpCommandReferenceUrl",
lambda config, *_: config.help_command_reference_url,
)
self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart)
self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown)
self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages)
self.set_field("maxSteamOfferCount", lambda config, *_: config.max_steam_offer_count)
self.set_field("maintenance", lambda config, *_: config.maintenance)
self.add_collection(
"featureFlag",
lambda config, *_: List(
any,
[{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags],
),
)
self.set_field("pingURLs", lambda config, *_: config.ping_urls)
self.set_field("technicianIds", lambda config, *_: config.technician_ids)
self.set_field("pingURLHistory", self.resolve_ping_url_history)
self.set_field("technicianIdHistory", self.resolve_technician_id_history)
def resolve_ping_url_history(self, entry: TableWithIdABC, *_):
history = List(TechnicianPingUrlConfigHistory)
results = self._db.select(
f"""
SELECT *
FROM CFG_TechnicianPingUrlsHistory
WHERE Id = {entry.id}
ORDER BY DateTo DESC;
"""
)
for result in results:
history.add(TechnicianPingUrlConfigHistory(*result[1:], result[0]))
return history
def resolve_technician_id_history(self, entry: TableWithIdABC, *_):
history = List(TechnicianIdConfigHistory)
results = self._db.select(
f"""
SELECT *
FROM CFG_TechnicianIdsHistory
WHERE Id = {entry.id}
ORDER BY DateTo DESC;
"""
)
for result in results:
history.add(TechnicianIdConfigHistory(*result[1:], result[0]))
return history

View File

@@ -1,8 +0,0 @@
from bot_graphql.abc.history_query_abc import HistoryQueryABC
class TechnicianIdConfigHistoryQuery(HistoryQueryABC):
def __init__(self):
HistoryQueryABC.__init__(self, "TechnicianIdConfig")
self.set_field("technicianId", lambda config, *_: config.technicianId)

View File

@@ -1,8 +0,0 @@
from bot_graphql.abc.history_query_abc import HistoryQueryABC
class TechnicianPingUrlConfigHistoryQuery(HistoryQueryABC):
def __init__(self):
HistoryQueryABC.__init__(self, "TechnicianPingUrlConfig")
self.set_field("url", lambda config, *_: config.ping_url)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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.achievements"
__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")

View File

@@ -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.achievements.commands"
__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")

View File

@@ -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.achievements.events"
__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")

Some files were not shown because too many files have changed in this diff Show More