Compare commits

..

No commits in common. "master" and "1.1.10" have entirely different histories.

938 changed files with 5479 additions and 13213 deletions

View File

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

View File

@ -1,120 +1,57 @@
name: Deploy prod on push
run-name: Deploy prod on push
name: Deploy dev on push
run-name: Deploy dev on push
on:
push:
branches:
- master
jobs:
pre-build:
on-push-deploy_sh-edraft:
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
container: catthehacker/ubuntu:act-latest
steps:
- name: Shutdown stack
run: docker stack rm sdb_prod
- name: Setup Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10.12"
- run: python -v
build-bot:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Setup docker
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: Shutdown stack
run: docker stack rm kdb_prod
- name: Prepare bot build
run: |
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
cd bot
cd kdb-bot
pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
cpl i
- name: Build docker bot
run: |
cd bot
cd kdb-bot
docker image prune -f
cpl build
docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv) .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd bot
docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)
build-web:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Setup docker
uses: https://github.com/papodaca/install-docker-action@main
- run: docker -v
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
cpl docker-build
- name: Setup node
uses: https://github.com/actions/setup-node@v3
- name: Prepare web build
run: |
cd web
cd kdb-web
npm install -g ts-node
npm ci
npm i
- name: Build docker web
run: |
cd web
cd kdb-web
docker image prune -f
npm run build
docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv) .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd web
docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)
deploy:
needs: [ build-bot, build-web ]
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- name: Install cpl
run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
- name: Set version
run: |
cd bot/docker
chmod +x ./set-docker-compose-image-version.sh
./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv) git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)
npm run docker-build
- name: Deploy Stack to sh-edraft.de
uses: https://github.com/kgierke/portainer-stack-deployment@v1
@ -123,6 +60,6 @@ jobs:
portainer-username: "gitea_job"
portainer-password: "${{ secrets.docker_job }}"
portainer-endpoint: 2
name: sdb_prod
file: bot/docker/docker-compose.yml
name: kdb_prod
file: ./docker-compose.yml
variables: '{}'

View File

@ -1,129 +0,0 @@
name: Deploy staging on push
run-name: Deploy staging on push
on:
push:
branches:
- staging
jobs:
pre-build:
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Shutdown stack
run: docker stack rm sdb_staging
build-bot:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Setup docker
uses: https://github.com/papodaca/install-docker-action@main
- run: docker -v
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- name: Prepare bot build
run: |
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
cd bot
cpl i
- name: Build docker bot
run: |
cd bot
docker image prune -f
cpl build
docker build -t git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-staging .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd bot
docker push git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cpl gv)-staging
build-web:
needs: pre-build
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Setup docker
uses: https://github.com/papodaca/install-docker-action@main
- run: docker -v
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- name: Setup node
uses: https://github.com/actions/setup-node@v3
- name: Prepare web build
run: |
cd web
npm install -g ts-node
npm ci
- name: Build docker web
run: |
cd web
docker image prune -f
cp src/favicon.staging.ico src/favicon.ico
npm run build
docker build -t git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-staging .
- name: Login to registry git.sh-edraft.de
uses: https://github.com/docker/login-action@v1
with:
registry: git.sh-edraft.de
username: ${{ secrets.CI_USERNAME }}
password: ${{ secrets.CI_ACCESS_TOKEN }}
- name: Push image
run: |
cd web
docker push git.sh-edraft.de/sh-edraft.de/sdb-web:$(npm run -s gv)-staging
deploy:
needs: [ build-bot, build-web ]
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
container: git.sh-edraft.de/sh-edraft.de/act-runner:latest
steps:
- name: Clone Repository
uses: https://github.com/actions/checkout@v3
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- name: Install cpl
run: python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
- name: Set version
run: |
cd bot/docker
chmod +x ./set-docker-compose-image-version.sh
./set-docker-compose-image-version.sh git.sh-edraft.de/sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-staging git.sh-edraft.de/sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-staging
- name: Deploy Stack to sh-edraft.de
uses: https://github.com/kgierke/portainer-stack-deployment@v1
with:
portainer-url: "https://docker.sh-edraft.de"
portainer-username: "gitea_job"
portainer-password: "${{ secrets.docker_job }}"
portainer-endpoint: 2
name: sdb_staging
file: bot/docker/docker-compose.staging.yml
variables: '{}'

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

@ -1 +0,0 @@
Subproject commit fbcd9226c4d199529fdbce5169b38b1b23074adb

@ -1 +0,0 @@
Subproject commit eeebd13f80c6ceecc922ede5771e55212a884019

View File

@ -1,22 +0,0 @@
import os
import shutil
from datetime import datetime
from cpl_core.application.application_extension_abc import ApplicationExtensionABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_query.extension import List
class CleanLogsExtension(ApplicationExtensionABC):
def __init__(self):
pass
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
(
List(str, os.listdir("logs/"))
.where(lambda x: os.path.isdir(f"logs/{x}"))
.order_by()
.where(lambda x: (datetime.now() - datetime.strptime(x, "%Y-%m-%d")).days >= 7)
.for_each(lambda x: shutil.rmtree(f"logs/{x}"))
)

@ -1 +0,0 @@
Subproject commit 12ffcbcd9b88612251a1e23cb6724e21562f74b8

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 ready {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,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 EventLogger(CustomFileLoggerABC):
def __init__(
self,
config: ConfigurationABC,
time_format: TimeFormatSettings,
env: ApplicationEnvironmentABC,
):
CustomFileLoggerABC.__init__(self, "Event", config, time_format, env)

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,319 +0,0 @@
from datetime import datetime, timedelta
from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.container import Member, Guild
from cpl_discord.service import DiscordBotServiceABC
from bot_core.abc.client_utils_abc import ClientUtilsABC
from bot_core.logging.database_logger import DatabaseLogger
from bot_core.pipes.date_time_offset_pipe import DateTimeOffsetPipe
from bot_data.abc.client_repository_abc import ClientRepositoryABC
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
from bot_data.abc.user_joined_game_server_repository_abc import (
UserJoinedGameServerRepositoryABC,
)
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
from bot_data.abc.user_joined_voice_channel_repository_abc import (
UserJoinedVoiceChannelRepositoryABC,
)
from bot_data.abc.user_repository_abc import UserRepositoryABC
from bot_data.model.client import Client
from bot_data.model.known_user import KnownUser
from bot_data.model.server import Server
from bot_data.model.server_config import ServerConfig
from bot_data.model.user import User
from bot_data.model.user_joined_server import UserJoinedServer
from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
from bot_data.service.user_repository_service import ServerRepositoryABC
from modules.achievements.achievement_service import AchievementService
class DataIntegrityService:
def __init__(
self,
config: ConfigurationABC,
logger: DatabaseLogger,
bot: DiscordBotServiceABC,
db_context: DatabaseContextABC,
server_repo: ServerRepositoryABC,
user_repo: UserRepositoryABC,
client_repo: ClientRepositoryABC,
known_users: KnownUserRepositoryABC,
user_joins: UserJoinedServerRepositoryABC,
user_joins_vc: UserJoinedVoiceChannelRepositoryABC,
user_joined_gs: UserJoinedGameServerRepositoryABC,
achievement_service: AchievementService,
client_utils: ClientUtilsABC,
dtp: DateTimeOffsetPipe,
):
self._config = config
self._logger = logger
self._bot = bot
self._db_context = db_context
self._servers = server_repo
self._users = user_repo
self._clients = client_repo
self._known_users = known_users
self._user_joins = user_joins
self._user_joins_vc = user_joins_vc
self._user_joined_gs = user_joined_gs
self._achievements = achievement_service
self._client_utils = client_utils
self._dtp = dtp
self._is_for_shutdown = False
async def check_data_integrity(self, is_for_shutdown=False):
self._logger.info(__name__, f"Data integrity service started")
if is_for_shutdown != self._is_for_shutdown:
self._is_for_shutdown = is_for_shutdown
try:
for g in self._bot.guilds:
self._logger.debug(__name__, f"Start check for server: {g.id}")
s = self._get_or_create_server(g)
self._logger.debug(__name__, f"Start check for clients")
self._check_clients(g.id, s)
for m in [m for m in g.members if not m.bot]:
await self._check_default_role(m)
self._check_known_user(m.id)
self._logger.debug(__name__, f"Start check for member: {g.id}@{m.id}")
u = self._get_or_create_user(s, m.id)
self._logger.debug(__name__, f"Start check for user joined server: {g.id}@{m.id}")
self._check_user_join(g, m, u)
self._logger.debug(__name__, f"Start check for user joined voice channels: {g.id}@{m.id}")
self._check_user_joined_vc(g.id, m, u)
self._logger.debug(__name__, f"Start check for user joined game servers: {g.id}@{m.id}")
self._check_user_joined_gs(g.id, m.id, u)
self._logger.debug(__name__, f"Start check for user got achievements: {g.id}@{m.id}")
await self._check_for_user_achievements(u)
for m in [m for m in g.members if m.bot]:
u = self._users.find_user_by_discord_id_and_server_id(m.id, s.id)
if u is None:
continue
self._remove_bot(u)
self._logger.info(__name__, f"Data integrity service finished")
except Exception as e:
self._logger.fatal(__name__, f"Checking data integrity failed", e)
def _get_or_create_server(self, guild: Guild) -> Server:
try:
server = self._servers.find_server_by_discord_id(guild.id)
if server is not None:
return server
self._logger.warn(__name__, f"Server not found in database: {guild.id}")
self._logger.debug(__name__, f"Add server: {guild.id}")
self._servers.add_server(Server(guild.id))
self._db_context.save_changes()
server = self._servers.find_server_by_discord_id(guild.id)
if server is None:
self._logger.fatal(__name__, f"Cannot add server: {guild.id}")
self._logger.trace(__name__, f"Added server: {guild.id}")
return server
except Exception as e:
self._logger.error(__name__, f"Cannot get server", e)
def _check_clients(self, guild_id: int, server: Server):
try:
client = self._clients.find_client_by_server_id(server.id)
if client is not None:
return
self._logger.warn(
__name__,
f"Client for server {guild_id} not found in database: {self._bot.user.id}",
)
self._logger.debug(__name__, f"Add client: {self._bot.user.id}")
self._clients.add_client(Client(self._bot.user.id, 0, 0, 0, 0, 0, server))
self._db_context.save_changes()
client = self._clients.find_client_by_server_id(server.id)
if client is None:
self._logger.fatal(
__name__,
f"Cannot add client {self._bot.user.id} for server {guild_id}",
)
self._logger.trace(__name__, f"Added client: {guild_id}")
except Exception as e:
self._logger.error(__name__, f"Cannot get client", e)
results = self._servers.get_servers()
if results is None or len(results) == 0:
self._logger.error(__name__, f"Table Servers is empty!")
def _check_known_user(self, member_id: int):
try:
if self._known_users.find_user_by_discord_id(member_id) is not None:
return
self._logger.warn(__name__, f"Unknown user: {member_id}")
self._logger.trace(__name__, f"Add known user: {member_id}")
self._known_users.add_user(KnownUser(member_id))
self._db_context.save_changes()
user = self._known_users.find_user_by_discord_id(member_id)
if user is None:
self._logger.fatal(__name__, f"Cannot add user: {member_id}")
self._logger.trace(__name__, f"Added known user: {member_id}")
except Exception as e:
self._logger.error(__name__, f"Cannot get user", e)
def _get_or_create_user(self, server: Server, member_id: int) -> User:
try:
user = self._users.find_user_by_discord_id_and_server_id(member_id, server.id)
if user is not None:
return user
self._logger.warn(__name__, f"User not found in database: {member_id}")
self._logger.debug(__name__, f"Add user: {member_id}")
self._users.add_user(User(member_id, 0, 0, 0, None, server))
self._db_context.save_changes()
self._logger.trace(__name__, f"Added User: {member_id}")
return self._users.get_user_by_discord_id_and_server_id(member_id, server.id)
except Exception as e:
self._logger.error(__name__, f"Cannot get User", e)
results = self._users.get_users()
if results is None or len(results) == 0:
self._logger.error(__name__, f"Table Users is empty!")
def _check_user_join(self, guild: Guild, member: Member, user: User):
try:
join = self._user_joins.find_active_user_joined_server_by_user_id(user.id)
if join is not None:
return
self._logger.warn(
__name__,
f"Active UserJoinedServer not found in database: {guild.id}:{member.id}@{member.joined_at}",
)
self._logger.debug(
__name__,
f"Add UserJoinedServer: {guild.id}:{member.id}@{member.joined_at}",
)
self._user_joins.add_user_joined_server(UserJoinedServer(user, self._dtp.transform(member.joined_at), None))
self._db_context.save_changes()
self._logger.trace(__name__, f"Added UserJoinedServer: {member.id}")
except Exception as e:
self._logger.error(__name__, f"Cannot get UserJoinedServer", e)
try:
joins = self._user_joins.get_user_joined_servers()
for join in [x for x in joins if x.user.server.discord_id == guild.id and x.leaved_on is None]:
dc_user = guild.get_member(join.user.discord_id)
if dc_user is not None:
continue
self._logger.warn(
__name__,
f"User {join.user.discord_id} already left the server.",
)
join.leaved_on = datetime.now()
self._user_joins.update_user_joined_server(join)
self._db_context.save_changes()
except Exception as e:
self._logger.error(__name__, f"Cannot update UserJoinedServer", e)
def _check_user_joined_vc(self, guild_id: int, member: Member, user: User):
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
try:
# close open voice states
joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.id)
if joins is None or len(joins) == 0:
return
for join in joins:
self._logger.warn(
__name__,
f"Active UserJoinedVoiceChannel found in database: {guild_id}:{member.id}@{join.joined_on}",
)
join.leaved_on = datetime.now()
if ((join.leaved_on - join.joined_on).total_seconds() / 60 / 60) > settings.max_voice_state_hours:
join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours)
self._user_joins_vc.update_user_joined_voice_channel(join)
if self._is_for_shutdown:
user.xp += round(join.time * settings.xp_per_ontime_hour)
self._users.update_user(user)
self._db_context.save_changes()
if self._is_for_shutdown:
return
# add open voice states
if member.voice is None or member.voice.channel.id in settings.afk_channel_ids:
return
join = UserJoinedVoiceChannel(user, member.voice.channel.id, datetime.now())
self._user_joins_vc.add_user_joined_voice_channel(join)
self._db_context.save_changes()
except Exception as e:
self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e)
def _check_user_joined_gs(self, guild_id: int, member_id: int, user: User):
try:
joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.id)
if joins is None or len(joins) == 0:
return
for join in joins:
self._logger.warn(
__name__,
f"Active UserJoinedGameServer found in database: {guild_id}:{member_id}@{join.joined_on}",
)
join.leaved_on = datetime.now()
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
if join.time > settings.max_voice_state_hours:
join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours)
self._user_joined_gs.update_user_joined_game_server(join)
if self._is_for_shutdown:
user.xp += round(join.time * settings.xp_per_ontime_hour)
self._users.update_user(user)
self._db_context.save_changes()
except Exception as e:
self._logger.error(__name__, f"Cannot get UserJoinedGameServer", e)
async def _check_for_user_achievements(self, user: User):
try:
await self._achievements.validate_achievements_for_user(user)
except Exception as e:
self._logger.error(__name__, f"Cannot check UserGotAchievement for {user.id}", e)
async def _check_default_role(self, member: Member):
await self._client_utils.check_default_role(member)
def _remove_bot(self, user: User):
known_user = self._known_users.find_user_by_discord_id(user.discord_id)
if known_user is not None:
self._known_users.delete_user(known_user)
for join in self._user_joins.get_user_joined_servers_by_user_id(user.id):
self._user_joins.delete_user_joined_server(join)
self._user_joins_vc.delete_user_joined_voice_channel_by_user_id(user.id)
self._users.delete_user(user)
self._db_context.save_changes()

View File

@ -1,129 +0,0 @@
from typing import Optional
import discord
from cpl_core.configuration import ConfigurationABC
from cpl_core.logging import LoggerABC
from cpl_discord.service import DiscordBotServiceABC
from bot_core.abc.permission_service_abc import PermissionServiceABC
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
class PermissionService(PermissionServiceABC):
def __init__(
self,
logger: LoggerABC,
bot: DiscordBotServiceABC,
config: ConfigurationABC,
servers: ServerRepositoryABC,
server_configs: ServerConfigRepositoryABC,
technician_configs: TechnicianConfigRepositoryABC,
):
PermissionServiceABC.__init__(self)
self._logger = logger
self._bot = bot
self._config = config
self._servers = servers
self._server_configs = server_configs
self._technician_configs = technician_configs
# member_id: {team_member_type: {guild_id: bool}}
self._cache: dict[int, dict[TeamMemberTypeEnum, dict[int, bool]]] = {}
def reset_cache(self):
self._cache = {}
def get_cached_permission(
self, member_id: int, team_member_type: TeamMemberTypeEnum, guild_id: int = None
) -> Optional[bool]:
if member_id not in self._cache:
self._cache[member_id] = {}
if team_member_type not in self._cache[member_id]:
self._cache[member_id][team_member_type] = {}
return None
if guild_id not in self._cache[member_id][team_member_type]:
return None
return self._cache[member_id][team_member_type][guild_id]
def set_cached_permission(
self, value: bool, member_id: int, team_member_type: TeamMemberTypeEnum, guild_id: int = None
):
if member_id not in self._cache:
self._cache[member_id] = {}
if team_member_type not in self._cache[member_id]:
self._cache[member_id][team_member_type] = {}
self._cache[member_id][team_member_type][guild_id] = value
def _has_member_role(self, member: discord.Member, team_member_type: TeamMemberTypeEnum) -> bool:
if member is None or member.guild is None:
return False
try:
has_permission_cached = self.get_cached_permission(member.id, team_member_type, member.guild.id)
if has_permission_cached is not None:
return has_permission_cached
self._logger.debug(__name__, f"Checking is member {member.name} {team_member_type.value}")
has_permission = True in [
member.guild.get_role(x.role_id) in member.roles
for x in self._server_configs.get_server_config_by_server(
self._servers.get_server_by_discord_id(member.guild.id).id
).team_role_ids
if x.team_member_type == team_member_type
]
self.set_cached_permission(has_permission, member.id, team_member_type, member.guild.id)
return has_permission
except Exception as e:
self._logger.error(__name__, "Permission check failed", e)
return False
def is_member_admin(self, member: discord.Member) -> bool:
return self._has_member_role(member, TeamMemberTypeEnum.admin)
def is_member_moderator(self, member: discord.Member) -> bool:
return self._has_member_role(member, TeamMemberTypeEnum.moderator) or self._has_member_role(
member, TeamMemberTypeEnum.admin
)
def is_member_technician(self, member: discord.Member) -> bool:
if member is None or member.guild is None:
return False
has_permission_cached = self.get_cached_permission(member.id, TeamMemberTypeEnum.technician)
if has_permission_cached is not None:
return has_permission_cached
self._logger.debug(__name__, f"Checking is member {member.name} technician")
try:
has_permission = member.id in self._technician_configs.get_technician_config().technician_ids
self.set_cached_permission(has_permission, member.id, TeamMemberTypeEnum.technician)
return has_permission
except Exception as e:
self._logger.error(__name__, "Permission check failed", e)
return False
def is_member_technician_by_id(self, member_id: int):
has_permission_cached = self.get_cached_permission(member_id, TeamMemberTypeEnum.technician)
if has_permission_cached is not None:
return has_permission_cached
self._logger.debug(__name__, f"Checking is member {member_id} technician")
try:
has_permission = member_id in self._technician_configs.get_technician_config().technician_ids
self.set_cached_permission(has_permission, member_id, TeamMemberTypeEnum.technician)
return has_permission
except Exception as e:
self._logger.error(__name__, "Permission check failed", e)
return False

View File

@ -1,35 +0,0 @@
from abc import ABC, abstractmethod
from cpl_query.extension import List
from bot_data.model.scheduled_event import ScheduledEvent
class ScheduledEventRepositoryABC(ABC):
@abstractmethod
def __init__(self):
pass
@abstractmethod
def get_scheduled_events(self) -> List[ScheduledEvent]:
pass
@abstractmethod
def get_scheduled_event_by_id(self, id: int) -> ScheduledEvent:
pass
@abstractmethod
def get_scheduled_events_by_server_id(self, id: int) -> List[ScheduledEvent]:
pass
@abstractmethod
def add_scheduled_event(self, scheduled_event: ScheduledEvent):
pass
@abstractmethod
def update_scheduled_event(self, scheduled_event: ScheduledEvent):
pass
@abstractmethod
def delete_scheduled_event(self, scheduled_event: ScheduledEvent):
pass

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,50 +0,0 @@
from typing import Optional
from cpl_core.database import DatabaseSettings
from cpl_core.database.connection import DatabaseConnectionABC
from mysql.connector.abstracts import MySQLConnectionAbstract
from mysql.connector.cursor import MySQLCursorBuffered
class DBConnection(DatabaseConnectionABC):
def __init__(self):
DatabaseConnectionABC.__init__(self)
self._database: Optional[MySQLConnectionAbstract] = None
self._cursor: Optional[MySQLCursorBuffered] = None
@property
def server(self) -> MySQLConnectionAbstract:
return self._database
@property
def cursor(self) -> MySQLCursorBuffered:
return self._cursor
def connect(self, settings: DatabaseSettings):
# connection = sql.connect(
# host=settings.host,
# port=settings.port,
# user=settings.user,
# passwd=CredentialManager.decrypt(settings.password),
# charset=settings.charset,
# use_unicode=settings.use_unicode,
# buffered=settings.buffered,
# auth_plugin=settings.auth_plugin,
# ssl_disabled=settings.ssl_disabled,
# )
# connection.cursor().execute(f"CREATE DATABASE IF NOT EXISTS `{settings.database}`;")
# self._database = sql.connect(
# host=settings.host,
# port=settings.port,
# user=settings.user,
# passwd=CredentialManager.decrypt(settings.password),
# db=settings.database,
# charset=settings.charset,
# use_unicode=settings.use_unicode,
# buffered=settings.buffered,
# auth_plugin=settings.auth_plugin,
# ssl_disabled=settings.ssl_disabled,
# )
self._
self._cursor = self._database.cursor()

View File

@ -1,17 +0,0 @@
class Migration:
def __init__(self, name: str, version: str, script: str):
self._name = name
self._version = version
self._script = script
@property
def name(self) -> str:
return self._name
@property
def version(self) -> str:
return self._version
@property
def script(self) -> str:
return self._script

View File

@ -1,188 +0,0 @@
from datetime import datetime
from typing import Optional
import discord
from cpl_core.database import TableABC
from bot_data.model.scheduled_event_interval_enum import ScheduledEventIntervalEnum
from bot_data.model.server import Server
class ScheduledEvent(TableABC):
def __init__(
self,
interval: ScheduledEventIntervalEnum,
name: str,
description: str,
channel_id: int,
start_time: datetime,
end_time: Optional[datetime],
entity_type: discord.EntityType,
location: Optional[str],
server: Optional[Server],
created_at: datetime = None,
modified_at: datetime = None,
id=0,
):
self._id = id
self._interval = interval
self._name = name
self._description = description
self._channel_id = channel_id
self._start_time = start_time
self._end_time = end_time
self._entity_type = entity_type
self._location = location
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 interval(self) -> ScheduledEventIntervalEnum:
return self._interval
@interval.setter
def interval(self, value: ScheduledEventIntervalEnum):
self._interval = value
@property
def name(self) -> str:
return self._name
@name.setter
def name(self, value: str):
self._name = value
@property
def description(self) -> str:
return self._description
@description.setter
def description(self, value: str):
self._description = value
@property
def channel_id(self) -> int:
return self._channel_id
@channel_id.setter
def channel_id(self, value: int):
self._channel_id = value
@property
def start_time(self) -> datetime:
return self._start_time
@start_time.setter
def start_time(self, value: datetime):
self._start_time = value
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, value: datetime):
self._end_time = value
@property
def entity_type(self) -> discord.EntityType:
return self._entity_type
@entity_type.setter
def entity_type(self, value: discord.EntityType):
self._entity_type = value
@property
def location(self) -> str:
return self._location
@location.setter
def location(self, value: str):
self._location = value
@property
def server(self) -> Server:
return self._server
@server.setter
def server(self, value: Server):
self._server = value
@staticmethod
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `ScheduledEvents`;
"""
)
@staticmethod
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `ScheduledEvents`
WHERE `Id` = {id};
"""
)
@staticmethod
def get_select_by_server_id_string(s_id: int) -> str:
return str(
f"""
SELECT * FROM `ScheduledEvents`
WHERE `ServerId` = {s_id};
"""
)
@property
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `ScheduledEvents` (
`Interval`, `Name`, `Description`, `ChannelId`, `StartTime`, `EndTime`, `EntityType`, `Location`, `ServerId`
) VALUES (
'{self._interval.value}',
'{self._name}',
{"NULL" if self._description is None else f"'{self._description}'"},
{"NULL" if self._channel_id is None else f"'{self._channel_id}'"},
'{self._start_time}',
{"NULL" if self._end_time is None else f"'{self._end_time}'"},
'{self._entity_type.value}',
{"NULL" if self._location is None else f"'{self._location}'"},
{self._server.id}
);
"""
)
@property
def udpate_string(self) -> str:
return str(
f"""
UPDATE `ScheduledEvents`
SET `Interval` = '{self._interval.value}',
`Name` = '{self._name}',
`Description` = {"NULL" if self._description is None else f"'{self._description}'"},
`ChannelId` = {"NULL" if self._channel_id is None else f"'{self._channel_id}'"},
`StartTime` = '{self._start_time}',
`EndTime` = {"NULL" if self._end_time is None else f"'{self._end_time}'"},
`EntityType` = '{self._entity_type.value}',
`Location` = {"NULL" if self._location is None else f"'{self._location}'"}
WHERE `Id` = {self._id};
"""
)
@property
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `ScheduledEvents`
WHERE `Id` = {self._id};
"""
)

View File

@ -1,118 +0,0 @@
from datetime import datetime
from typing import Optional
import discord
from cpl_core.database import TableABC
from bot_data.abc.history_table_abc import HistoryTableABC
from bot_data.model.server import Server
class ScheduledEventHistory(HistoryTableABC):
def __init__(
self,
interval: str,
name: str,
description: str,
channel_id: int,
start_time: datetime,
end_time: Optional[datetime],
entity_type: discord.EntityType,
location: Optional[str],
server: Optional[Server],
deleted: bool,
date_from: str,
date_to: str,
id=0,
):
HistoryTableABC.__init__(self)
self._id = id
self._interval = interval
self._name = name
self._description = description
self._channel_id = channel_id
self._start_time = start_time
self._end_time = end_time
self._entity_type = entity_type
self._location = location
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 interval(self) -> str:
return self._interval
@interval.setter
def interval(self, value: str):
self._interval = value
@property
def name(self) -> str:
return self._name
@name.setter
def name(self, value: str):
self._name = value
@property
def description(self) -> str:
return self._description
@description.setter
def description(self, value: str):
self._description = value
@property
def channel_id(self) -> int:
return self._channel_id
@channel_id.setter
def channel_id(self, value: int):
self._channel_id = value
@property
def start_time(self) -> datetime:
return self._start_time
@start_time.setter
def start_time(self, value: datetime):
self._start_time = value
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, value: datetime):
self._end_time = value
@property
def entity_type(self) -> discord.EntityType:
return self._entity_type
@entity_type.setter
def entity_type(self, value: discord.EntityType):
self._entity_type = value
@property
def location(self) -> str:
return self._location
@location.setter
def location(self, value: str):
self._location = value
@property
def server(self) -> Server:
return self._server
@server.setter
def server(self, value: Server):
self._server = value

View File

@ -1,8 +0,0 @@
from enum import Enum
class ScheduledEventIntervalEnum(Enum):
daily = "daily"
weekly = "weekly"
monthly = "monthly"
yearly = "yearly"

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,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,104 +0,0 @@
# https://stackoverflow.com/questions/32658679/how-to-create-a-mysql-connection-pool-or-any-better-way-to-initialize-the-multip
import mysql.connector as sql
from cpl_core.database import DatabaseSettings
from cpl_core.utils import CredentialManager
class MySQLPool(object):
"""
create a pool when connect mysql, which will decrease the time spent in
request connection, create connection and close connection.
"""
def __init__(
self,
database_settings: DatabaseSettings,
pool_size=5,
):
res = {
"host": database_settings.host,
"port": database_settings.port,
"user": database_settings.user,
"password": CredentialManager.decrypt(database_settings.password),
"database": database_settings.database,
}
self.dbconfig = res
self.pool = self.create_pool(pool_name="MySqlPool", pool_size=pool_size)
def create_pool(self, pool_name="MySqlPool", pool_size=3):
"""
Create a connection pool, after created, the request of connecting
MySQL could get a connection from this pool instead of request to
create a connection.
:param pool_name: the name of pool, default is "mypool"
:param pool_size: the size of pool, default is 3
:return: connection pool
"""
pool = sql.pooling.MySQLConnectionPool(
pool_name=pool_name, pool_size=pool_size, pool_reset_session=True, **self.dbconfig
)
return pool
def close(self, conn, cursor):
"""
A method used to close connection of mysql.
:param conn:
:param cursor:
:return:
"""
cursor.close()
conn.close()
def execute(self, sql, args=None, commit=False):
"""
Execute a sql, it could be with args and with out args. The usage is
similar with execute() function in module pymysql.
:param sql: sql clause
:param args: args need by sql clause
:param commit: whether to commit
:return: if commit, return None, else, return result
"""
# get connection form connection pool instead of create one.
conn = self.pool.get_connection()
cursor = conn.cursor()
if args:
cursor.execute(sql, args)
else:
cursor.execute(sql)
if commit is True:
conn.commit()
self.close(conn, cursor)
return None
else:
res = cursor.fetchall()
self.close(conn, cursor)
return res
def executemany(self, sql, args, commit=False):
"""
Execute with many args. Similar with executemany() function in pymysql.
args should be a sequence.
:param sql: sql clause
:param args: args
:param commit: commit or not.
:return: if commit, return None, else, return result
"""
# get connection form connection pool instead of create one.
conn = self.pool.get_connection()
cursor = conn.cursor()
cursor.executemany(sql, args)
if commit is True:
conn.commit()
self.close(conn, cursor)
return None
else:
res = cursor.fetchall()
self.close(conn, cursor)
return res
def commit(self):
conn = self.pool.get_connection()
conn.commit()
cursor = conn.cursor()
self.close(conn, cursor)

View File

@ -1,12 +0,0 @@
DROP TABLE `Servers`;
DROP TABLE `Users`;
DROP TABLE `Clients`;
DROP TABLE `KnownUsers`;
DROP TABLE `UserJoinedServers`;
DROP TABLE `UserJoinedVoiceChannel`;

View File

@ -1,80 +0,0 @@
CREATE TABLE IF NOT EXISTS `MigrationHistory`
(
`MigrationId` VARCHAR(255),
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`MigrationId`)
);
CREATE TABLE IF NOT EXISTS `Servers`
(
`ServerId` BIGINT NOT NULL AUTO_INCREMENT,
`DiscordServerId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`ServerId`)
);
CREATE TABLE IF NOT EXISTS `Users`
(
`UserId` BIGINT NOT NULL AUTO_INCREMENT,
`DiscordId` BIGINT NOT NULL,
`XP` BIGINT NOT NULL DEFAULT 0,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
FOREIGN KEY (`ServerId`) REFERENCES Servers (`ServerId`),
PRIMARY KEY (`UserId`)
);
CREATE TABLE IF NOT EXISTS `Clients`
(
`ClientId` BIGINT NOT NULL AUTO_INCREMENT,
`DiscordClientId` BIGINT NOT NULL,
`SentMessageCount` BIGINT NOT NULL DEFAULT 0,
`ReceivedMessageCount` BIGINT NOT NULL DEFAULT 0,
`DeletedMessageCount` BIGINT NOT NULL DEFAULT 0,
`ReceivedCommandsCount` BIGINT NOT NULL DEFAULT 0,
`MovedUsersCount` BIGINT NOT NULL DEFAULT 0,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
FOREIGN KEY (`ServerId`) REFERENCES Servers (`ServerId`),
PRIMARY KEY (`ClientId`)
);
CREATE TABLE IF NOT EXISTS `KnownUsers`
(
`KnownUserId` BIGINT NOT NULL AUTO_INCREMENT,
`DiscordId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`KnownUserId`)
);
CREATE TABLE IF NOT EXISTS `UserJoinedServers`
(
`JoinId` BIGINT NOT NULL AUTO_INCREMENT,
`UserId` BIGINT NOT NULL,
`JoinedOn` DATETIME(6) NOT NULL,
`LeavedOn` DATETIME(6),
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
FOREIGN KEY (`UserId`) REFERENCES Users (`UserId`),
PRIMARY KEY (`JoinId`)
);
CREATE TABLE IF NOT EXISTS `UserJoinedVoiceChannel`
(
`JoinId` BIGINT NOT NULL AUTO_INCREMENT,
`UserId` BIGINT NOT NULL,
`DiscordChannelId` BIGINT NOT NULL,
`JoinedOn` DATETIME(6) NOT NULL,
`LeavedOn` DATETIME(6),
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
FOREIGN KEY (`UserId`) REFERENCES Users (`UserId`),
PRIMARY KEY (`JoinId`)
);

View File

@ -1,4 +0,0 @@
DROP TABLE `AutoRoleRules`;
DROP TABLE `AutoRoles`;

View File

@ -1,26 +0,0 @@
CREATE TABLE IF NOT EXISTS `AutoRoles`
(
`AutoRoleId` BIGINT NOT NULL AUTO_INCREMENT,
`ServerId` BIGINT,
`DiscordMessageId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`AutoRoleId`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers` (`ServerId`)
);
CREATE TABLE IF NOT EXISTS `AutoRoleRules`
(
`AutoRoleRuleId` BIGINT NOT NULL AUTO_INCREMENT,
`AutoRoleId` BIGINT,
`DiscordEmojiName` VARCHAR(64),
`DiscordRoleId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`AutoRoleRuleId`),
FOREIGN KEY (`AutoRoleId`) REFERENCES `AutoRoles` (`AutoRoleId`)
);

View File

@ -1,4 +0,0 @@
DROP TABLE `AuthUserUsersRelations`;
DROP TABLE `AuthUsers`;

View File

@ -1,34 +0,0 @@
CREATE TABLE IF NOT EXISTS `AuthUsers`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`FirstName` VARCHAR(255),
`LastName` VARCHAR(255),
`EMail` VARCHAR(255),
`Password` VARCHAR(255),
`PasswordSalt` VARCHAR(255),
`RefreshToken` VARCHAR(255),
`ConfirmationId` VARCHAR(255) DEFAULT NULL,
`ForgotPasswordId` VARCHAR(255) DEFAULT NULL,
`OAuthId` VARCHAR(255) DEFAULT NULL,
`RefreshTokenExpiryTime` DATETIME(6) NOT NULL,
`AuthRole` INT NOT NULL DEFAULT 0,
`CreatedAt` DATETIME(6) NOT NULL,
`LastModifiedAt` DATETIME(6) NOT NULL,
PRIMARY KEY (`Id`)
);
CREATE TABLE IF NOT EXISTS `AuthUserUsersRelations`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`AuthUserId` BIGINT DEFAULT NULL,
`UserId` BIGINT DEFAULT NULL,
`CreatedAt` DATETIME(6) NOT NULL,
`LastModifiedAt` DATETIME(6) NOT NULL,
PRIMARY KEY (`Id`),
FOREIGN KEY (`AuthUserId`) REFERENCES `AuthUsers` (`Id`),
FOREIGN KEY (`UserId`) REFERENCES `Users` (`UserId`)
);

View File

@ -1,2 +0,0 @@
DROP TABLE `Levels`;

View File

@ -1,15 +0,0 @@
CREATE TABLE IF NOT EXISTS `Levels`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(255) NOT NULL,
`Color` VARCHAR(8) NOT NULL,
`MinXp` BIGINT NOT NULL,
`PermissionInt` BIGINT NOT NULL,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers` (`ServerId`)
);

View File

@ -1,2 +0,0 @@
DROP TABLE `Statistics`;

View File

@ -1,14 +0,0 @@
CREATE TABLE IF NOT EXISTS `Statistics`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`Code` LONGTEXT NOT NULL,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers` (`ServerId`)
);

View File

@ -1,4 +0,0 @@
ALTER TABLE AutoRoles
DROP COLUMN DiscordChannelId;

View File

@ -1,4 +0,0 @@
ALTER TABLE AutoRoles
ADD DiscordChannelId BIGINT NOT NULL AFTER ServerId;

View File

@ -1,2 +0,0 @@
DROP TABLE `UserMessageCountPerHour`;

View File

@ -1,14 +0,0 @@
CREATE TABLE IF NOT EXISTS `UserMessageCountPerHour`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Date` DATETIME(6) NOT NULL,
`Hour` BIGINT,
`XPCount` BIGINT,
`UserId` BIGINT,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`UserId`) REFERENCES `Users` (`UserId`)
);

View File

@ -1,2 +0,0 @@
DROP TABLE `ApiKeys`;

View File

@ -1,15 +0,0 @@
CREATE TABLE IF NOT EXISTS `ApiKeys`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Identifier` VARCHAR(255) NOT NULL,
`Key` VARCHAR(255) NOT NULL,
`CreatorId` BIGINT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`CreatorId`) REFERENCES `Users` (`UserId`),
CONSTRAINT UC_Identifier_Key UNIQUE (`Identifier`, `Key`),
CONSTRAINT UC_Key UNIQUE (`Key`)
);

View File

@ -1,8 +0,0 @@
DROP TABLE `UserJoinedGameServer`;
DROP TABLE `UserGameIdents`;
DROP TABLE `GameServers`;

View File

@ -1,46 +0,0 @@
CREATE TABLE IF NOT EXISTS `GameServers`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(255) NOT NULL,
`ServerId` BIGINT NOT NULL,
`ApiKeyId` BIGINT NOT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
FOREIGN KEY (`ServerId`) REFERENCES Servers (`ServerId`),
FOREIGN KEY (`ApiKeyId`) REFERENCES ApiKeys (`Id`),
PRIMARY KEY (`Id`)
);
CREATE TABLE IF NOT EXISTS `UserJoinedGameServer`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`UserId` BIGINT NOT NULL,
`GameServerId` BIGINT NOT NULL,
`JoinedOn` DATETIME(6) NOT NULL,
`LeavedOn` DATETIME(6),
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
FOREIGN KEY (`UserId`) REFERENCES Users (`UserId`),
FOREIGN KEY (`GameServerId`) REFERENCES GameServers (`Id`),
PRIMARY KEY (`Id`)
);
CREATE TABLE IF NOT EXISTS `UserGameIdents`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`UserId` BIGINT NOT NULL,
`GameServerId` BIGINT NOT NULL,
`Ident` VARCHAR(255) NOT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
FOREIGN KEY (`UserId`) REFERENCES Users (`UserId`),
FOREIGN KEY (`GameServerId`) REFERENCES GameServers (`Id`),
CONSTRAINT UC_UserGameIdent UNIQUE (`GameServerId`, `Ident`),
PRIMARY KEY (`Id`)
);

View File

@ -1,14 +0,0 @@
CREATE TABLE IF NOT EXISTS `Statistics`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`Code` LONGTEXT NOT NULL,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers` (`ServerId`)
);

View File

@ -1,3 +0,0 @@
DROP TABLE IF EXISTS `Statistics`;

View File

@ -1,2 +0,0 @@
DROP TABLE `UserWarnings`;

View File

@ -1,14 +0,0 @@
CREATE TABLE IF NOT EXISTS `UserWarnings`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Description` VARCHAR(255) NOT NULL,
`UserId` BIGINT NOT NULL,
`Author` BIGINT NULL,
`CreatedAt` DATETIME(6),
`LastModifiedAt` DATETIME(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`UserId`) REFERENCES `Users` (`UserId`),
FOREIGN KEY (`Author`) REFERENCES `Users` (`UserId`)
);

View File

@ -1,34 +0,0 @@
DROP TABLE `ApiKeysHistory`;
DROP TABLE `AuthUsersHistory`;
DROP TABLE `AuthUserUsersRelationsHistory`;
DROP TABLE `AutoRoleRulesHistory`;
DROP TABLE `AutoRolesHistory`;
DROP TABLE `ClientsHistory`;
DROP TABLE `GameServersHistory`;
DROP TABLE `KnownUsersHistory`;
DROP TABLE `LevelsHistory`;
DROP TABLE `ServersHistory`;
DROP TABLE `UserGameIdentsHistory`;
DROP TABLE `UserJoinedGameServerHistory`;
DROP TABLE `UserJoinedServersHistory`;
DROP TABLE `UserJoinedVoiceChannelHistory`;
DROP TABLE `UserMessageCountPerHourHistory`;
DROP TABLE `UsersHistory`;
DROP TABLE `UserWarningsHistory`;

View File

@ -1,711 +0,0 @@
ALTER TABLE `ApiKeys`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `ApiKeys`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `ApiKeysHistory`
(
`Id` BIGINT(20) NOT NULL,
`Identifier` VARCHAR(255) NOT NULL,
`Key` VARCHAR(255) NOT NULL,
`CreatorId` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_ApiKeysUpdate`;;
CREATE TRIGGER `TR_ApiKeysUpdate`
AFTER UPDATE
ON `ApiKeys`
FOR EACH ROW
BEGIN
INSERT INTO `ApiKeysHistory` (`Id`, `Identifier`, `Key`, `CreatorId`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Identifier, OLD.Key, OLD.CreatorId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_ApiKeysDelete`;;
CREATE TRIGGER `TR_ApiKeysDelete`
AFTER DELETE
ON `ApiKeys`
FOR EACH ROW
BEGIN
INSERT INTO `ApiKeysHistory` (`Id`, `Identifier`, `Key`, `CreatorId`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Identifier, OLD.Key, OLD.CreatorId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `AuthUsers`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `AuthUsers`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `AuthUsersHistory`
(
`Id` BIGINT(20) NOT NULL,
`FirstName` VARCHAR(255) DEFAULT NULL,
`LastName` VARCHAR(255) DEFAULT NULL,
`EMail` VARCHAR(255) DEFAULT NULL,
`Password` VARCHAR(255) DEFAULT NULL,
`PasswordSalt` VARCHAR(255) DEFAULT NULL,
`RefreshToken` VARCHAR(255) DEFAULT NULL,
`ConfirmationId` VARCHAR(255) DEFAULT NULL,
`ForgotPasswordId` VARCHAR(255) DEFAULT NULL,
`OAuthId` VARCHAR(255) DEFAULT NULL,
`RefreshTokenExpiryTime` DATETIME(6) NOT NULL,
`AuthRole` BIGINT(11) NOT NULL DEFAULT 0,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_AuthUsersUpdate`;;
CREATE TRIGGER `TR_AuthUsersUpdate`
AFTER UPDATE
ON `AuthUsers`
FOR EACH ROW
BEGIN
INSERT INTO `AuthUsersHistory` (`Id`, `FirstName`, `LastName`, `EMail`, `Password`, `PasswordSalt`,
`RefreshToken`, `ConfirmationId`, `ForgotPasswordId`, `OAuthId`,
`RefreshTokenExpiryTime`, `AuthRole`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.FirstName, OLD.LastName, OLD.EMail, OLD.Password, OLD.PasswordSalt, OLD.RefreshToken,
OLD.ConfirmationId, OLD.ForgotPasswordId, OLD.OAuthId, OLD.RefreshTokenExpiryTime, OLD.AuthRole,
OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_AuthUsersDelete`;;
CREATE TRIGGER `TR_AuthUsersDelete`
AFTER DELETE
ON `AuthUsers`
FOR EACH ROW
BEGIN
INSERT INTO `AuthUsersHistory` (`Id`, `FirstName`, `LastName`, `EMail`, `Password`, `PasswordSalt`, `RefreshToken`,
`ConfirmationId`, `ForgotPasswordId`, `OAuthId`, `RefreshTokenExpiryTime`,
`AuthRole`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.FirstName, OLD.LastName, OLD.EMail, OLD.Password, OLD.PasswordSalt, OLD.RefreshToken,
OLD.ConfirmationId, OLD.ForgotPasswordId, OLD.OAuthId, OLD.RefreshTokenExpiryTime, OLD.AuthRole, TRUE,
OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `AuthUserUsersRelations`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `AuthUserUsersRelations`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `AuthUserUsersRelationsHistory`
(
`Id` BIGINT(20) NOT NULL,
`AuthUserId` BIGINT(20) DEFAULT NULL,
`UserId` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_AuthUserUsersRelationsUpdate`;;
CREATE TRIGGER `TR_AuthUserUsersRelationsUpdate`
AFTER UPDATE
ON `AuthUserUsersRelations`
FOR EACH ROW
BEGIN
INSERT INTO `AuthUserUsersRelationsHistory` (`Id`, `AuthUserId`, `UserId`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.AuthUserId, OLD.UserId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_AuthUserUsersRelationsDelete`;;
CREATE TRIGGER `TR_AuthUserUsersRelationsDelete`
AFTER DELETE
ON `AuthUserUsersRelations`
FOR EACH ROW
BEGIN
INSERT INTO `AuthUserUsersRelationsHistory` (`Id`, `AuthUserId`, `UserId`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.AuthUserId, OLD.UserId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `AutoRoleRules`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `AutoRoleRules`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `AutoRoleRulesHistory`
(
`Id` BIGINT(20) NOT NULL,
`AutoRoleId` BIGINT(20) DEFAULT NULL,
`DiscordEmojiName` VARCHAR(64) DEFAULT NULL,
`DiscordRoleId` BIGINT(20) NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_AutoRoleRulesUpdate`;;
CREATE TRIGGER `TR_AutoRoleRulesUpdate`
AFTER UPDATE
ON `AutoRoleRules`
FOR EACH ROW
BEGIN
INSERT INTO `AutoRoleRulesHistory` (`Id`, `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `DateFrom`, `DateTo`)
VALUES (OLD.AutoRoleRuleId, OLD.AutoRoleId, OLD.DiscordEmojiName, OLD.DiscordRoleId, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_AutoRoleRulesDelete`;;
CREATE TRIGGER `TR_AutoRoleRulesDelete`
AFTER DELETE
ON `AutoRoleRules`
FOR EACH ROW
BEGIN
INSERT INTO `AutoRoleRulesHistory` (`Id`, `AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `Deleted`, `DateFrom`,
`DateTo`)
VALUES (OLD.AutoRoleRuleId, OLD.AutoRoleId, OLD.DiscordEmojiName, OLD.DiscordRoleId, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `AutoRoles`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `AutoRoles`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `AutoRolesHistory`
(
`Id` BIGINT(20) NOT NULL,
`ServerId` BIGINT(20) DEFAULT NULL,
`DiscordChannelId` BIGINT(20) NOT NULL,
`DiscordMessageId` BIGINT(20) NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_AutoRolesUpdate`;;
CREATE TRIGGER `TR_AutoRolesUpdate`
AFTER UPDATE
ON `AutoRoles`
FOR EACH ROW
BEGIN
INSERT INTO `AutoRolesHistory` (`Id`, `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `DateFrom`, `DateTo`)
VALUES (OLD.AutoRoleId, OLD.ServerId, OLD.DiscordChannelId, OLD.DiscordMessageId, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_AutoRolesDelete`;;
CREATE TRIGGER `TR_AutoRolesDelete`
AFTER DELETE
ON `AutoRoles`
FOR EACH ROW
BEGIN
INSERT INTO `AutoRolesHistory` (`Id`, `ServerId`, `DiscordChannelId`, `DiscordMessageId`, `Deleted`, `DateFrom`,
`DateTo`)
VALUES (OLD.AutoRoleId, OLD.ServerId, OLD.DiscordChannelId, OLD.DiscordMessageId, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `Clients`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `Clients`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `ClientsHistory`
(
`Id` BIGINT(20) NOT NULL,
`DiscordId` BIGINT(20) NOT NULL,
`SentMessageCount` BIGINT(20) NOT NULL DEFAULT 0,
`ReceivedMessageCount` BIGINT(20) NOT NULL DEFAULT 0,
`DeletedMessageCount` BIGINT(20) NOT NULL DEFAULT 0,
`ReceivedCommandsCount` BIGINT(20) NOT NULL DEFAULT 0,
`MovedUsersCount` BIGINT(20) NOT NULL DEFAULT 0,
`ServerId` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_ClientsUpdate`;;
CREATE TRIGGER `TR_ClientsUpdate`
AFTER UPDATE
ON `Clients`
FOR EACH ROW
BEGIN
INSERT INTO `ClientsHistory` (`Id`, `DiscordId`, `SentMessageCount`, `ReceivedMessageCount`, `DeletedMessageCount`,
`ReceivedCommandsCount`, `MovedUsersCount`, `ServerId`, `DateFrom`, `DateTo`)
VALUES (OLD.ClientId, OLD.DiscordClientId, OLD.SentMessageCount, OLD.ReceivedMessageCount, OLD.DeletedMessageCount,
OLD.ReceivedCommandsCount, OLD.MovedUsersCount, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_ClientsDelete`;;
CREATE TRIGGER `TR_ClientsDelete`
AFTER DELETE
ON `Clients`
FOR EACH ROW
BEGIN
INSERT INTO `ClientsHistory` (`Id`, `DiscordId`, `SentMessageCount`, `ReceivedMessageCount`, `DeletedMessageCount`,
`ReceivedCommandsCount`, `MovedUsersCount`, `ServerId`, `Deleted`, `DateFrom`,
`DateTo`)
VALUES (OLD.ClientId, OLD.DiscordClientId, OLD.SentMessageCount, OLD.ReceivedMessageCount, OLD.DeletedMessageCount,
OLD.ReceivedCommandsCount, OLD.MovedUsersCount, OLD.ServerId, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `GameServers`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `GameServers`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `GameServersHistory`
(
`Id` BIGINT(20) NOT NULL,
`Name` VARCHAR(255) NOT NULL,
`ServerId` BIGINT(20) NOT NULL,
`ApiKeyId` BIGINT(20) NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_GameServersUpdate`;;
CREATE TRIGGER `TR_GameServersUpdate`
AFTER UPDATE
ON `GameServers`
FOR EACH ROW
BEGIN
INSERT INTO `GameServersHistory` (`Id`, `Name`, `ServerId`, `ApiKeyId`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Name, OLD.ServerId, OLD.ApiKeyId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_GameServersDelete`;;
CREATE TRIGGER `TR_GameServersDelete`
AFTER DELETE
ON `GameServers`
FOR EACH ROW
BEGIN
INSERT INTO `GameServersHistory` (`Id`, `Name`, `ServerId`, `ApiKeyId`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Name, OLD.ServerId, OLD.ApiKeyId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `KnownUsers`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `KnownUsers`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `KnownUsersHistory`
(
`Id` BIGINT(20) NOT NULL,
`DiscordId` BIGINT(20) NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_KnownUsersUpdate`;;
CREATE TRIGGER `TR_KnownUsersUpdate`
AFTER UPDATE
ON `KnownUsers`
FOR EACH ROW
BEGIN
INSERT INTO `KnownUsersHistory` (`Id`, `DiscordId`, `DateFrom`, `DateTo`)
VALUES (OLD.KnownUserId, OLD.DiscordId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_KnownUsersDelete`;;
CREATE TRIGGER `TR_KnownUsersDelete`
AFTER DELETE
ON `KnownUsers`
FOR EACH ROW
BEGIN
INSERT INTO `KnownUsersHistory` (`Id`, `DiscordId`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.KnownUserId, OLD.DiscordId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `Levels`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `Levels`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `LevelsHistory`
(
`Id` BIGINT(20) NOT NULL,
`Name` VARCHAR(255) NOT NULL,
`Color` VARCHAR(8) NOT NULL,
`MinXp` BIGINT(20) NOT NULL,
`PermissionInt` BIGINT(20) NOT NULL,
`ServerId` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_LevelsUpdate`;;
CREATE TRIGGER `TR_LevelsUpdate`
AFTER UPDATE
ON `Levels`
FOR EACH ROW
BEGIN
INSERT INTO `LevelsHistory` (`Id`, `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Name, OLD.Color, OLD.MinXp, OLD.PermissionInt, OLD.ServerId, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_LevelsDelete`;;
CREATE TRIGGER `TR_LevelsDelete`
AFTER DELETE
ON `Levels`
FOR EACH ROW
BEGIN
INSERT INTO `LevelsHistory` (`Id`, `Name`, `Color`, `MinXp`, `PermissionInt`, `ServerId`, `Deleted`, `DateFrom`,
`DateTo`)
VALUES (OLD.Id, OLD.Name, OLD.Color, OLD.MinXp, OLD.PermissionInt, OLD.ServerId, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `Servers`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `Servers`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `ServersHistory`
(
`Id` BIGINT(20) NOT NULL,
`DiscordId` BIGINT(20) NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_ServersUpdate`;;
CREATE TRIGGER `TR_ServersUpdate`
AFTER UPDATE
ON `Servers`
FOR EACH ROW
BEGIN
INSERT INTO `ServersHistory` (`Id`, `DiscordId`, `DateFrom`, `DateTo`)
VALUES (OLD.ServerId, OLD.DiscordServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_ServersDelete`;;
CREATE TRIGGER `TR_ServersDelete`
AFTER DELETE
ON `Servers`
FOR EACH ROW
BEGIN
INSERT INTO `ServersHistory` (`Id`, `DiscordId`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.ServerId, OLD.DiscordServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `UserGameIdents`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `UserGameIdents`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `UserGameIdentsHistory`
(
`Id` BIGINT(20) NOT NULL,
`UserId` BIGINT(20) NOT NULL,
`GameServerId` BIGINT(20) NOT NULL,
`Ident` VARCHAR(255) NOT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_UserGameIdentsUpdate`;;
CREATE TRIGGER `TR_UserGameIdentsUpdate`
AFTER UPDATE
ON `UserGameIdents`
FOR EACH ROW
BEGIN
INSERT INTO `UserGameIdentsHistory` (`Id`, `UserId`, `GameServerId`, `Ident`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.UserId, OLD.GameServerId, OLD.Ident, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_UserGameIdentsDelete`;;
CREATE TRIGGER `TR_UserGameIdentsDelete`
AFTER DELETE
ON `UserGameIdents`
FOR EACH ROW
BEGIN
INSERT INTO `UserGameIdentsHistory` (`Id`, `UserId`, `GameServerId`, `Ident`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.UserId, OLD.GameServerId, OLD.Ident, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `UserJoinedGameServer`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `UserJoinedGameServer`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `UserJoinedGameServerHistory`
(
`Id` BIGINT(20) NOT NULL,
`UserId` BIGINT(20) NOT NULL,
`GameServerId` BIGINT(20) NOT NULL,
`JoinedOn` DATETIME(6) NOT NULL,
`LeavedOn` DATETIME(6) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_UserJoinedGameServerUpdate`;;
CREATE TRIGGER `TR_UserJoinedGameServerUpdate`
AFTER UPDATE
ON `UserJoinedGameServer`
FOR EACH ROW
BEGIN
INSERT INTO `UserJoinedGameServerHistory` (`Id`, `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `DateFrom`,
`DateTo`)
VALUES (OLD.Id, OLD.UserId, OLD.GameServerId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_UserJoinedGameServerDelete`;;
CREATE TRIGGER `TR_UserJoinedGameServerDelete`
AFTER DELETE
ON `UserJoinedGameServer`
FOR EACH ROW
BEGIN
INSERT INTO `UserJoinedGameServerHistory` (`Id`, `UserId`, `GameServerId`, `JoinedOn`, `LeavedOn`, `Deleted`,
`DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.UserId, OLD.GameServerId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `UserJoinedServers`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `UserJoinedServers`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `UserJoinedServersHistory`
(
`Id` BIGINT(20) NOT NULL,
`UserId` BIGINT(20) NOT NULL,
`JoinedOn` DATETIME(6) NOT NULL,
`LeavedOn` DATETIME(6) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_UserJoinedServersUpdate`;;
CREATE TRIGGER `TR_UserJoinedServersUpdate`
AFTER UPDATE
ON `UserJoinedServers`
FOR EACH ROW
BEGIN
INSERT INTO `UserJoinedServersHistory` (`Id`, `UserId`, `JoinedOn`, `LeavedOn`, `DateFrom`, `DateTo`)
VALUES (OLD.JoinId, OLD.UserId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_UserJoinedServersDelete`;;
CREATE TRIGGER `TR_UserJoinedServersDelete`
AFTER DELETE
ON `UserJoinedServers`
FOR EACH ROW
BEGIN
INSERT INTO `UserJoinedServersHistory` (`Id`, `UserId`, `JoinedOn`, `LeavedOn`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.JoinId, OLD.UserId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `UserJoinedVoiceChannel`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `UserJoinedVoiceChannel`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `UserJoinedVoiceChannelHistory`
(
`Id` BIGINT(20) NOT NULL,
`UserId` BIGINT(20) NOT NULL,
`DiscordChannelId` BIGINT(20) NOT NULL,
`JoinedOn` DATETIME(6) NOT NULL,
`LeavedOn` DATETIME(6) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_UserJoinedVoiceChannelUpdate`;;
CREATE TRIGGER `TR_UserJoinedVoiceChannelUpdate`
AFTER UPDATE
ON `UserJoinedVoiceChannel`
FOR EACH ROW
BEGIN
INSERT INTO `UserJoinedVoiceChannelHistory` (`Id`, `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `DateFrom`,
`DateTo`)
VALUES (OLD.JoinId, OLD.UserId, OLD.DiscordChannelId, OLD.JoinedOn, OLD.LeavedOn, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_UserJoinedVoiceChannelDelete`;;
CREATE TRIGGER `TR_UserJoinedVoiceChannelDelete`
AFTER DELETE
ON `UserJoinedVoiceChannel`
FOR EACH ROW
BEGIN
INSERT INTO `UserJoinedVoiceChannelHistory` (`Id`, `UserId`, `DiscordChannelId`, `JoinedOn`, `LeavedOn`, `Deleted`,
`DateFrom`, `DateTo`)
VALUES (OLD.JoinId, OLD.UserId, OLD.DiscordChannelId, OLD.JoinedOn, OLD.LeavedOn, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `UserMessageCountPerHour`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `UserMessageCountPerHour`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `UserMessageCountPerHourHistory`
(
`Id` BIGINT(20) NOT NULL,
`Date` DATETIME(6) NOT NULL,
`Hour` BIGINT(20) DEFAULT NULL,
`XPCount` BIGINT(20) DEFAULT NULL,
`UserId` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_UserMessageCountPerHourUpdate`;;
CREATE TRIGGER `TR_UserMessageCountPerHourUpdate`
AFTER UPDATE
ON `UserMessageCountPerHour`
FOR EACH ROW
BEGIN
INSERT INTO `UserMessageCountPerHourHistory` (`Id`, `UserId`, `Date`, `Hour`, `XPCount`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.UserId, OLD.Date, OLD.Hour, OLD.XPCount, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_UserMessageCountPerHourDelete`;;
CREATE TRIGGER `TR_UserMessageCountPerHourDelete`
AFTER DELETE
ON `UserMessageCountPerHour`
FOR EACH ROW
BEGIN
INSERT INTO `UserMessageCountPerHourHistory` (`Id`, `UserId`, `Date`, `Hour`, `XPCount`, `Deleted`, `DateFrom`,
`DateTo`)
VALUES (OLD.Id, OLD.UserId, OLD.Date, OLD.Hour, OLD.XPCount, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
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,
`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`, `ServerId`,
`DateFrom`, `DateTo`)
VALUES (OLD.UserId, OLD.DiscordId, OLD.XP, 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`, `ServerId`,
`Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.UserId, OLD.DiscordId, OLD.XP, OLD.ServerId, TRUE,
OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
ALTER TABLE `UserWarnings`
CHANGE `CreatedAt` `CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6);;
ALTER TABLE `UserWarnings`
CHANGE `LastModifiedAt` `LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);;
CREATE TABLE IF NOT EXISTS `UserWarningsHistory`
(
`Id` BIGINT(20) NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`UserId` BIGINT(20) NOT NULL,
`Author` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);;
DROP TRIGGER IF EXISTS `TR_UserWarningsUpdate`;;
CREATE TRIGGER `TR_UserWarningsUpdate`
AFTER UPDATE
ON `UserWarnings`
FOR EACH ROW
BEGIN
INSERT INTO `UserWarningsHistory` (`Id`, `Description`, `UserId`, `Author`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Description, OLD.UserId, OLD.Author, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;
DROP TRIGGER IF EXISTS `TR_UserWarningsDelete`;;
CREATE TRIGGER `TR_UserWarningsDelete`
AFTER DELETE
ON `UserWarnings`
FOR EACH ROW
BEGIN
INSERT INTO `UserWarningsHistory` (`Id`, `Description`, `UserId`, `Author`, `Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Description, OLD.UserId, OLD.Author, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;

View File

@ -1,10 +0,0 @@
DROP TABLE `UserGotAchievements`;
DROP TABLE `Achievements`;
ALTER TABLE Users DROP COLUMN MessageCount;
ALTER TABLE Users DROP COLUMN ReactionCount;
DROP TABLE `AchievementsHistory`;

View File

@ -1,88 +0,0 @@
CREATE TABLE IF NOT EXISTS `Achievements`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`Attribute` VARCHAR(255) NOT NULL,
`Operator` VARCHAR(255) NOT NULL,
`Value` VARCHAR(255) NOT NULL,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`ServerId`) REFERENCES `Servers` (`ServerId`)
);
CREATE TABLE IF NOT EXISTS `AchievementsHistory`
(
`Id` BIGINT(20) NOT NULL,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`Attribute` VARCHAR(255) NOT NULL,
`Operator` VARCHAR(255) NOT NULL,
`Value` VARCHAR(255) NOT NULL,
`ServerId` BIGINT,
`Deleted` BOOL DEFAULT FALSE,
`DateFrom` DATETIME(6) NOT NULL,
`DateTo` DATETIME(6) NOT NULL
);
CREATE TABLE IF NOT EXISTS `UserGotAchievements`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`UserId` BIGINT,
`AchievementId` BIGINT,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (`Id`),
FOREIGN KEY (`UserId`) REFERENCES `Users` (`UserId`),
FOREIGN KEY (`AchievementId`) REFERENCES `Achievements` (`Id`)
);
ALTER TABLE Users
ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
ALTER TABLE Users
ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
ALTER TABLE UsersHistory
ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
ALTER TABLE UsersHistory
ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;
DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;
CREATE TRIGGER `TR_AchievementsUpdate`
AFTER UPDATE
ON `Achievements`
FOR EACH ROW
BEGIN
INSERT INTO `AchievementsHistory` (`Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`,
`DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;
DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;
CREATE TRIGGER `TR_AchievementsDelete`
AFTER DELETE
ON `Achievements`
FOR EACH ROW
BEGIN
INSERT INTO `AchievementsHistory` (`Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`,
`Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, TRUE,
OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;

View File

@ -1,24 +0,0 @@
DROP TABLE `CFG_ServerTeamRoleIds`;
DROP TABLE `CFG_ServerTeamRoleIdsHistory`;
DROP TABLE `CFG_ServerAFKChannelIds`;
DROP TABLE `CFG_ServerAFKChannelIdsHistory`;
DROP TABLE `CFG_Server`;
DROP TABLE `CFG_ServerHistory`;
DROP TABLE `CFG_TechnicianPingUrls`;
DROP TABLE `CFG_TechnicianPingUrlsHistory`;
DROP TABLE `CFG_TechnicianIds`;
DROP TABLE `CFG_TechnicianIdsHistory`;
DROP TABLE `CFG_Technician`;
DROP TABLE `CFG_TechnicianHistory`;

View File

@ -1,452 +0,0 @@
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`)
);
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`)
);
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`)
);
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`)
);
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`)
);
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`)
);
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,
`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`,
`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.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`,
`ServerId`,
`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.ServerId,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
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;;
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;;
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,
`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`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.HelpCommandReferenceUrl,
OLD.WaitForRestart,
OLD.WaitForShutdown,
OLD.CacheMaxMessages,
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`,
`Deleted`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.HelpCommandReferenceUrl,
OLD.WaitForRestart,
OLD.WaitForShutdown,
OLD.CacheMaxMessages,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
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;;
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,4 +0,0 @@
ALTER TABLE CFG_Technician DROP COLUMN FeatureFlags;
ALTER TABLE CFG_Server DROP COLUMN FeatureFlags;

View File

@ -1,6 +0,0 @@
ALTER TABLE CFG_Technician
ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;
ALTER TABLE CFG_Server
ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;

View File

@ -1,4 +0,0 @@
ALTER TABLE CFG_Server
DROP COLUMN DefaultRoleId;

View File

@ -1,4 +0,0 @@
ALTER TABLE CFG_Server
ADD DefaultRoleId BIGINT NULL AFTER LoginMessageChannelId;

View File

@ -1,4 +0,0 @@
DROP TABLE `ShortRoleNames`;
DROP TABLE `ShortRoleNamesHistory`;

View File

@ -1,10 +0,0 @@
ALTER TABLE CFG_ServerHistory
DROP COLUMN DefaultRoleId;
ALTER TABLE CFG_TechnicianHistory
DROP COLUMN FeatureFlags;
ALTER TABLE CFG_ServerHistory
DROP COLUMN FeatureFlags;

View File

@ -1,171 +0,0 @@
ALTER TABLE CFG_ServerHistory
ADD DefaultRoleId BIGINT NULL AFTER LoginMessageChannelId;
ALTER TABLE CFG_TechnicianHistory
ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;
ALTER TABLE CFG_ServerHistory
ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;
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`,
`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.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`,
`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.FeatureFlags,
OLD.ServerId,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;
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,
`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`,
`FeatureFlags`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.HelpCommandReferenceUrl,
OLD.WaitForRestart,
OLD.WaitForShutdown,
OLD.CacheMaxMessages,
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`,
`FeatureFlags`,
`Deleted`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id,
OLD.HelpCommandReferenceUrl,
OLD.WaitForRestart,
OLD.WaitForShutdown,
OLD.CacheMaxMessages,
OLD.FeatureFlags,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;

View File

@ -1,9 +0,0 @@
ALTER TABLE CFG_Server
DROP COLUMN ShortRoleNameSetOnlyHighest;
ALTER TABLE CFG_ServerHistory
DROP COLUMN ShortRoleNameSetOnlyHighest;

View File

@ -1,9 +0,0 @@
ALTER TABLE UsersHistory
DROP COLUMN MessageCount;
ALTER TABLE UsersHistory
DROP COLUMN ReactionCount;

View File

@ -1,32 +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);;
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`, `ServerId`,
`DateFrom`, `DateTo`)
VALUES (OLD.UserId, OLD.DiscordId, OLD.XP, OLD.ReactionCount, OLD.MessageCount, 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`, `ServerId`,
`Deleted`, `DateFrom`, `DateTo`)
VALUES (OLD.UserId, OLD.DiscordId, OLD.XP, OLD.ReactionCount, OLD.MessageCount, OLD.ServerId, TRUE,
OLD.LastModifiedAt, CURRENT_TIMESTAMP(6));
END;;

View File

@ -1,19 +0,0 @@
ALTER TABLE Users
DROP COLUMN Birthday;
ALTER TABLE UsersHistory
DROP COLUMN Birthday;
ALTER TABLE CFG_Server
DROP COLUMN XpForBirthday;
ALTER TABLE CFG_ServerHistory
DROP COLUMN XpForBirthday;

View File

@ -1,150 +0,0 @@
ALTER TABLE Users
ADD Birthday DATE NULL AFTER MessageCount;
ALTER TABLE UsersHistory
ADD Birthday DATE NULL AFTER MessageCount;
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);;
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;;
ALTER TABLE CFG_Server
ADD XpForBirthday BIGINT(20) NOT NULL DEFAULT 0 AFTER XpPerAchievement;
ALTER TABLE CFG_ServerHistory
ADD XpForBirthday BIGINT(20) NOT NULL DEFAULT 0 AFTER XpPerAchievement;
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,11 +0,0 @@
DROP TABLE `SteamSpecialOffers`;
ALTER TABLE CFG_Server
DROP COLUMN GameOfferNotificationChatId;
ALTER TABLE CFG_ServerHistory
DROP COLUMN GameOfferNotificationChatId;

View File

@ -1,23 +0,0 @@
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`)
);
ALTER TABLE CFG_Server
ADD COLUMN GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;
ALTER TABLE CFG_ServerHistory
ADD COLUMN GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;

View File

@ -1,9 +0,0 @@
ALTER TABLE CFG_Technician
DROP COLUMN MaxSteamOfferCount;
ALTER TABLE CFG_TechnicianHistory
DROP COLUMN MaxSteamOfferCount;

View File

@ -1,9 +0,0 @@
ALTER TABLE CFG_Technician
DROP COLUMN Maintenance;
ALTER TABLE CFG_TechnicianHistory
DROP COLUMN Maintenance;

View File

@ -1,66 +0,0 @@
ALTER TABLE CFG_Technician
ADD Maintenance BOOLEAN DEFAULT FALSE AFTER MaxSteamOfferCount;
ALTER TABLE CFG_TechnicianHistory
ADD Maintenance BOOLEAN DEFAULT FALSE AFTER MaxSteamOfferCount;
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,3 +0,0 @@
DROP TABLE `ShortRoleNames`;
DROP TABLE `ShortRoleNamesHistory`;

View File

@ -1,83 +0,0 @@
CREATE TABLE IF NOT EXISTS `ScheduledEvents`
(
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Interval` ENUM ('daily', 'weekly', 'monthly', 'yearly') NOT NULL,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NULL,
`ChannelId` BIGINT NULL,
`StartTime` DATETIME(6) NOT NULL,
`EndTime` DATETIME(6) NULL,
`EntityType` ENUM ('1','2','3') NOT NULL,
`Location` VARCHAR(255) 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`)
);
CREATE TABLE IF NOT EXISTS `ScheduledEventsHistory`
(
`Id` BIGINT(20) NOT NULL,
`Interval` ENUM ('daily', 'weekly', 'monthly', 'yearly') NOT NULL,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NULL,
`ChannelId` BIGINT NULL,
`StartTime` DATETIME(6) NOT NULL,
`EndTime` DATETIME(6) NULL,
`EntityType` ENUM ('1','2','3') NOT NULL,
`Location` VARCHAR(255) 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_ScheduledEventsUpdate`;
CREATE TRIGGER `TR_ScheduledEventsUpdate`
AFTER UPDATE
ON `ScheduledEvents`
FOR EACH ROW
BEGIN
INSERT INTO `ScheduledEventsHistory` (`Id`,
`Interval`,
`Name`,
`Description`,
`ChannelId`,
`StartTime`,
`EndTime`,
`EntityType`,
`Location`,
`ServerId`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id, OLD.Interval, OLD.Name, OLD.Description, OLD.ChannelId, OLD.StartTime, OLD.EndTime, OLD.EntityType,
OLD.Location, OLD.ServerId, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;
DROP TRIGGER IF EXISTS `TR_ScheduledEventsDelete`;
CREATE TRIGGER `TR_ScheduledEventsDelete`
AFTER DELETE
ON `ScheduledEvents`
FOR EACH ROW
BEGIN
INSERT INTO `ScheduledEventsHistory` (`Id`,
`Interval`,
`Name`,
`Description`,
`ChannelId`,
`StartTime`,
`EndTime`,
`EntityType`,
`Location`,
`ServerId`,
`Deleted`,
`DateFrom`,
`DateTo`)
VALUES (OLD.Id, OLD.Interval, OLD.Name, OLD.Description, OLD.ChannelId, OLD.StartTime, OLD.EndTime, OLD.EntityType,
OLD.Location, OLD.ServerId, TRUE, OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;

View File

@ -1,7 +0,0 @@
ALTER TABLE CFG_Server
DROP COLUMN ResetMemberAfterRejoin;
ALTER TABLE CFG_ServerHistory
DROP COLUMN ResetMemberAfterRejoin;

View File

@ -1,116 +0,0 @@
ALTER TABLE CFG_Server
ADD ResetMemberAfterRejoin BOOLEAN NOT NULL DEFAULT FALSE AFTER GameOfferNotificationChatId;
ALTER TABLE CFG_ServerHistory
ADD ResetMemberAfterRejoin BOOLEAN NOT NULL DEFAULT FALSE AFTER GameOfferNotificationChatId;
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`,
`GameOfferNotificationChatId`,
`ResetMemberAfterRejoin`,
`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.GameOfferNotificationChatId,
OLD.ResetMemberAfterRejoin,
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`,
`GameOfferNotificationChatId`,
`ResetMemberAfterRejoin`,
`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.GameOfferNotificationChatId,
OLD.ResetMemberAfterRejoin,
OLD.FeatureFlags,
OLD.ServerId,
TRUE,
OLD.LastModifiedAt,
CURRENT_TIMESTAMP(6));
END;;

View File

@ -1,158 +0,0 @@
import glob
import os
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_query.extension import List
from packaging import version
import bot
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.db_context import DBContext
from bot_data.model.migration import Migration
from bot_data.model.migration_history import MigrationHistory
class MigrationService:
def __init__(
self,
logger: DatabaseLogger,
services: ServiceProviderABC,
db: DBContext,
):
self._logger = logger
self._services = services
self._db = db
def _get_migration_history(self) -> List[MigrationHistory]:
results = self._db.select(
"""
SELECT * FROM `MigrationHistory`
"""
)
applied_migrations = List(MigrationHistory)
for result in results:
applied_migrations.add(MigrationHistory(result[0], result[1]))
return applied_migrations
def _migration_migrations_to_old(self, migration: MigrationHistory):
if migration.migration_id.endswith("Migration"):
return
self._logger.debug(__name__, f"Migrate new migration {migration.migration_id} to old method")
self._db.execute(migration.change_id_string(f"{migration.migration_id}Migration"))
self._db.save_changes()
def _migration_migrations_to_new(self, migration: MigrationHistory):
if not migration.migration_id.endswith("Migration"):
return
self._logger.debug(__name__, f"Migrate old migration {migration.migration_id} to new method")
self._db.execute(migration.change_id_string(migration.migration_id.replace("Migration", "")))
self._db.save_changes()
def _migrate_from_old_to_new(self):
result = self._db.select("SHOW TABLES LIKE 'MigrationHistory'")
if not result:
return
for migration in self._get_migration_history():
if version.Version(bot.__version__) < version.Version("1.2.2"):
self._migration_migrations_to_old(migration)
else:
self._migration_migrations_to_new(migration)
def _load_scripts(self, upgrade: bool = True) -> List[Migration]:
migrations = List(Migration)
path = "../bot_data/scripts"
if not os.path.exists(path):
raise Exception("Migration path not found")
folders = List(str, glob.glob(f"{path}/*"))
if upgrade:
folders = folders.order_by()
else:
folders = folders.order_by_descending()
for folder in folders:
splitted = folder.split("/")
version_str = splitted[len(splitted) - 1]
# upgrade do not run migrations from higher versions
if upgrade and version.Version(version_str) > version.Version(bot.__version__):
break
# downgrade run migrations from higher versions
if not upgrade and version.Version(version_str) <= version.Version(bot.__version__):
continue
files = List(str, os.listdir(folder)).where(lambda x: x.endswith(f"_{'up' if upgrade else 'down'}.sql"))
if upgrade:
files = files.order_by()
else:
files = files.order_by_descending()
for file in files.to_list():
if not file.endswith(".sql"):
continue
name = str(file.split(".sql")[0])
if name.endswith("_up"):
name = name.replace("_up", "")
elif name.endswith("_down"):
name = name.replace("_down", "")
name = name.split("_")[1]
with open(f"{folder}/{file}", "r") as f:
script = f.read()
f.close()
migrations.add(Migration(name, version_str, script))
return migrations
def _execute(self, migrations: List[Migration], upgrade: bool = True):
for migration in migrations:
active_statement = ""
try:
# check if table exists
result = self._db.select("SHOW TABLES LIKE 'MigrationHistory'")
if result:
# there is a table named "tableName"
self._logger.trace(
__name__,
f"Running SQL Command: {MigrationHistory.get_select_by_id_string(migration.name)}",
)
migration_from_db = self._db.select(MigrationHistory.get_select_by_id_string(migration.name))
if upgrade and migration_from_db is not None and len(migration_from_db) > 0:
continue
elif not upgrade and (migration_from_db is None or len(migration_from_db) == 0):
continue
self._logger.debug(
__name__, f"Running {'upgrade' if upgrade else 'downgrade'} migration: {migration.name}"
)
for statement in migration.script.split("\n\n"):
if statement in ["", "\n"]:
continue
active_statement = statement
self._db.execute(statement + ";")
self._db.execute(
MigrationHistory(migration.name).insert_string
if upgrade
else MigrationHistory(migration.name).delete_string
)
self._db.save_changes()
except Exception as e:
self._logger.fatal(
__name__, f"Migration failed: {migration.version}-{migration.name}\n{active_statement}", e
)
def migrate(self):
self._migrate_from_old_to_new()
self._execute(self._load_scripts())
self._execute(self._load_scripts(False), False)

View File

@ -1,91 +0,0 @@
from typing import Optional
from cpl_core.database.context import DatabaseContextABC
from cpl_query.extension import List
from discord import EntityType
from bot_core.logging.database_logger import DatabaseLogger
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.scheduled_event import ScheduledEvent
from bot_data.model.scheduled_event_interval_enum import ScheduledEventIntervalEnum
class ScheduledEventRepositoryService(ScheduledEventRepositoryABC):
def __init__(
self,
logger: DatabaseLogger,
db_context: DatabaseContextABC,
servers: ServerRepositoryABC,
):
self._logger = logger
self._context = db_context
self._servers = servers
ScheduledEventRepositoryABC.__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 _scheduled_event_from_result(self, sql_result: tuple) -> ScheduledEvent:
return ScheduledEvent(
self._get_value_from_result(ScheduledEventIntervalEnum(sql_result[1])), # interval
self._get_value_from_result(sql_result[2]), # name
self._get_value_from_result(sql_result[3]), # description
int(self._get_value_from_result(sql_result[4])), # channel_id
self._get_value_from_result(sql_result[5]), # start_time
self._get_value_from_result(sql_result[6]), # end_time
EntityType(int(self._get_value_from_result(sql_result[7]))), # entity_type
self._get_value_from_result(sql_result[8]), # location
self._servers.get_server_by_id((sql_result[9])), # server
self._get_value_from_result(sql_result[10]), # created_at
self._get_value_from_result(sql_result[11]), # modified_at
id=self._get_value_from_result(sql_result[0]),
)
def get_scheduled_events(self) -> List[ScheduledEvent]:
self._logger.trace(__name__, f"Send SQL command: {ScheduledEvent.get_select_all_string()}")
return List(
ScheduledEvent,
[
self._scheduled_event_from_result(result)
for result in self._context.select(ScheduledEvent.get_select_all_string())
],
)
def get_scheduled_event_by_id(self, id: int) -> ScheduledEvent:
self._logger.trace(__name__, f"Send SQL command: {ScheduledEvent.get_select_by_id_string(id)}")
return self._scheduled_event_from_result(self._context.select(ScheduledEvent.get_select_by_id_string(id))[0])
def get_scheduled_events_by_server_id(self, server_id: int) -> List[ScheduledEvent]:
self._logger.trace(
__name__,
f"Send SQL command: {ScheduledEvent.get_select_by_server_id_string(server_id)}",
)
return List(
ScheduledEvent,
[
self._scheduled_event_from_result(result)
for result in self._context.select(ScheduledEvent.get_select_by_server_id_string(server_id))
],
)
def add_scheduled_event(self, scheduled_event: ScheduledEvent):
self._logger.trace(__name__, f"Send SQL command: {scheduled_event.insert_string}")
self._context.cursor.execute(scheduled_event.insert_string)
def update_scheduled_event(self, scheduled_event: ScheduledEvent):
self._logger.trace(__name__, f"Send SQL command: {scheduled_event.udpate_string}")
self._context.cursor.execute(scheduled_event.udpate_string)
def delete_scheduled_event(self, scheduled_event: ScheduledEvent):
self._logger.trace(__name__, f"Send SQL command: {scheduled_event.delete_string}")
self._context.cursor.execute(scheduled_event.delete_string)

View File

@ -1,74 +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]:
self._logger.trace(__name__, f"Send SQL command: {SteamSpecialOffer.get_select_all_string()}")
return List(
SteamSpecialOffer,
[
self._steam_special_offer_from_result(result)
for result in self._context.select(SteamSpecialOffer.get_select_all_string())
],
)
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)}",
)
return self._steam_special_offer_from_result(
self._context.select(SteamSpecialOffer.get_select_by_name_string(name))[0]
)
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,213 +0,0 @@
import datetime
from typing import Optional
from cpl_core.database.context import DatabaseContextABC
from cpl_core.type import T, R
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.user_repository_abc import UserRepositoryABC
from bot_data.model.user import User
class UserRepositoryService(UserRepositoryABC):
def __init__(
self,
logger: DatabaseLogger,
db_context: DatabaseContextABC,
servers: ServerRepositoryABC,
):
self._logger = logger
self._context = db_context
self._servers = servers
UserRepositoryABC.__init__(self)
def _from_result(self, result: tuple):
return User(
result[1],
result[2],
result[3],
result[4],
result[5],
self._servers.get_server_by_id(result[6]),
result[7],
result[8],
id=result[0],
)
def get_users(self) -> List[User]:
self._logger.trace(__name__, f"Send SQL command: {User.get_select_all_string()}")
return List(
User, [self._from_result(user) for user in self._context.select(User.get_select_all_string())]
).for_each(lambda x: self._set_user_activity(x))
def get_user_by_id(self, id: int) -> User:
self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}")
result = self._context.select(User.get_select_by_id_string(id))[0]
return self._from_result(result)
def find_user_by_id(self, id: int) -> Optional[User]:
self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}")
result = self._context.select(User.get_select_by_id_string(id))
if result is None or len(result) == 0:
return None
return self._from_result(result[0])
def get_users_by_discord_id(self, discord_id: int) -> List[User]:
self._logger.trace(
__name__,
f"Send SQL command: {User.get_select_by_discord_id_string(discord_id)}",
)
return List(
User,
[
self._from_result(user)
for user in self._context.select(User.get_select_by_discord_id_string(discord_id))
],
)
def get_users_by_server_id(self, server_id: int) -> List[User]:
self._logger.trace(
__name__,
f"Send SQL command: {User.get_select_by_server_id_string(server_id)}",
)
return List(
User,
[self._from_result(user) for user in self._context.select(User.get_select_by_server_id_string(server_id))],
)
def get_users_with_activity_by_server_id(self, server_id: int) -> List[User]:
self._logger.trace(
__name__,
f"Send SQL command: {User.get_select_by_server_id_string(server_id)}",
)
return List(
User,
[self._from_result(user) for user in self._context.select(User.get_select_by_server_id_string(server_id))],
).for_each(lambda x: self._set_user_activity(x))
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
self._logger.trace(
__name__,
f"Send SQL command: {User.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}",
)
return self._from_result(
self._context.select(User.get_select_by_discord_id_and_server_id_string(discord_id, server_id))[0]
)
def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]:
self._logger.trace(
__name__,
f"Send SQL command: {User.get_select_by_discord_id_and_server_id_string(discord_id, server_id)}",
)
result = self._context.select(User.get_select_by_discord_id_and_server_id_string(discord_id, server_id))
if result is None or len(result) == 0:
return None
return self._from_result(result[0])
def add_user(self, user: User):
self._logger.trace(__name__, f"Send SQL command: {user.insert_string}")
self._context.cursor.execute(user.insert_string)
def update_user(self, user: User):
self._logger.trace(__name__, f"Send SQL command: {user.udpate_string}")
self._context.cursor.execute(user.udpate_string)
def delete_user(self, user: User):
self._logger.trace(__name__, f"Send SQL command: {user.delete_string}")
self._context.cursor.execute(user.delete_string)
def _set_user_activity(self, user):
days = (datetime.date.today() - (datetime.date.today() - datetime.timedelta(days=7))).days
query = f"""
SELECT (
(
SELECT Count(UserGotAchievements.CreatedAt)
FROM UserGotAchievements
INNER JOIN Achievements ON UserGotAchievements.AchievementId = Achievements.Id
INNER JOIN Users ON UserGotAchievements.UserId = Users.UserId
WHERE Users.ServerId = {user.server.id}
AND Users.UserId = {user.id}
AND UserGotAchievements.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
) +
(
SELECT SUM(
UserMessageCountPerHour.XPCount / (
SELECT XpPerMessage
FROM CFG_Server
WHERE ServerId = {user.server.id}
)
)
FROM UserMessageCountPerHour
INNER JOIN Users ON UserMessageCountPerHour.UserId = Users.UserId
WHERE Users.ServerId = {user.server.id}
AND Users.UserId = {user.id}
AND UserMessageCountPerHour.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
) +
(
SELECT Count(UserJoinedVoiceChannel.CreatedAt)
FROM UserJoinedVoiceChannel
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
WHERE Users.ServerId = {user.server.id}
AND Users.UserId = {user.id}
AND UserJoinedVoiceChannel.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
) +
(
SELECT IFNULL(ROUND(SUM(TIME_TO_SEC(
TIMEDIFF(UserJoinedVoiceChannel.LeavedOn, UserJoinedVoiceChannel.JoinedOn)
) / 3600), 2), 0)
FROM UserJoinedVoiceChannel
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
WHERE Users.ServerId = {user.server.id}
AND Users.UserId = {user.id}
AND UserJoinedVoiceChannel.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
) +
(
SELECT Count(UserJoinedGameServer.CreatedAt)
FROM UserJoinedGameServer
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
WHERE Users.ServerId = {user.server.id}
AND Users.UserId = {user.id}
AND UserJoinedGameServer.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
) +
(
SELECT IFNULL(ROUND(SUM(TIME_TO_SEC(
TIMEDIFF(UserJoinedGameServer.LeavedOn, UserJoinedGameServer.JoinedOn)
) / 3600), 2), 0)
FROM UserJoinedGameServer
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
WHERE Users.ServerId = {user.server.id}
AND Users.UserId = {user.id}
AND UserJoinedGameServer.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
) -
(
SELECT COUNT(UserWarnings.CreatedAt)
FROM UserWarnings
INNER JOIN Users ON UserWarnings.UserId = Users.UserId
WHERE Users.ServerId = {user.server.id}
AND Users.UserId = {user.id}
AND UserWarnings.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
)
) / {days} * 1000 as count;
"""
user.activity = self._cast_query_result(query, int)
def _cast_query_result(self, query: str, r_type: T) -> Optional[R]:
results = self._context.select(query)
if len(results) == 0 or len(results[0]) == 0:
return None
result = results[0][0]
default = None
if r_type is int or r_type is float:
default = 0
elif r_type is str:
default = ""
return r_type(result) if result is not None else default

View File

@ -1,17 +0,0 @@
from cpl_core.application import StartupExtensionABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironmentABC
from bot_data.service.migration_service import MigrationService
class StartupMigrationExtension(StartupExtensionABC):
def __init__(self):
pass
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
pass
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
services.add_transient(MigrationService)

View File

@ -1,71 +0,0 @@
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from bot_data.model.scheduled_event import ScheduledEvent
from bot_graphql.abc.filter_abc import FilterABC
class ScheduledEventFilter(FilterABC):
def __init__(self, bot: DiscordBotServiceABC, services: ServiceProviderABC):
FilterABC.__init__(self)
self._bot = bot
self._services = services
self._id = None
self._interval = None
self._name = None
self._description = None
self._channel_id = None
self._start_time = None
self._end_time = None
self._entity_type = None
self._location = None
self._server = None
def from_dict(self, values: dict):
self._get_attributes_from_dict(
[
("id", int),
("interval", str),
("name", str),
("description", str),
("channel_id", str),
("start_time", str),
("end_time", str),
("entity_type", str),
("location", str),
],
values,
)
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[ScheduledEvent]) -> List[ScheduledEvent]:
if self._id is not None:
query = query.where(lambda x: x.id == self._id)
query = self._filter_by_attributes(
[
{"attr": self._id, "func": lambda x: x.id == self._id},
{"attr": self._interval, "func": lambda x: x.interval == self._interval},
{"attr": self._name, "func": lambda x: x.name == self._name},
{"attr": self._description, "func": lambda x: x.description == self._description},
{"attr": self._channel_id, "func": lambda x: x.channel_id == self._channel_id},
{"attr": self._start_time, "func": lambda x: x.start_time == self._start_time},
{"attr": self._end_time, "func": lambda x: x.end_time == self._end_time},
{"attr": self._entity_type, "func": lambda x: x.entity_type == self._entity_type},
{"attr": self._location, "func": lambda x: x.location == self._location},
],
query,
)
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.user.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,68 +0,0 @@
type ScheduledEvent implements TableWithHistoryQuery {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
server: Server
createdAt: String
modifiedAt: String
history: [ScheduledEventHistory]
}
type ScheduledEventHistory implements HistoryTableQuery {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
server: ID
deleted: Boolean
dateFrom: String
dateTo: String
}
input ScheduledEventFilter {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
server: ServerFilter
}
type ScheduledEventMutation {
createScheduledEvent(input: ScheduledEventInput!): ScheduledEvent
updateScheduledEvent(input: ScheduledEventInput!): ScheduledEvent
deleteScheduledEvent(id: ID): ScheduledEvent
}
input ScheduledEventInput {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
serverId: ID
}

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,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,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,107 +0,0 @@
from datetime import datetime
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC
from discord import EntityType
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
from bot_data.model.scheduled_event import ScheduledEvent
from bot_data.model.scheduled_event_interval_enum import ScheduledEventIntervalEnum
from bot_data.model.user_role_enum import UserRoleEnum
from bot_graphql.abc.query_abc import QueryABC
from bot_core.service.permission_service import PermissionService
class ScheduledEventMutation(QueryABC):
def __init__(
self,
servers: ServerRepositoryABC,
scheduled_events: ScheduledEventRepositoryABC,
bot: DiscordBotServiceABC,
db: DatabaseContextABC,
permissions: PermissionService,
):
QueryABC.__init__(self, "ScheduledEventMutation")
self._servers = servers
self._scheduled_events = scheduled_events
self._bot = bot
self._db = db
self._permissions = permissions
self.set_field("createScheduledEvent", self.resolve_create_scheduled_event)
self.set_field("updateScheduledEvent", self.resolve_update_scheduled_event)
self.set_field("deleteScheduledEvent", self.resolve_delete_scheduled_event)
def resolve_create_scheduled_event(self, *_, input: dict):
server = self._servers.get_server_by_id(input["serverId"])
self._can_user_mutate_data(server, UserRoleEnum.moderator)
scheduled_event = ScheduledEvent(
ScheduledEventIntervalEnum(input["interval"]),
input["name"],
input["description"] if "description" in input else None,
input["channelId"] if "channelId" in input else None,
datetime.strptime(input["startTime"], "%Y-%m-%dT%H:%M:%S.%fZ"),
datetime.strptime(input["endTime"], "%Y-%m-%dT%H:%M:%S.%fZ") if "endTime" in input else None,
EntityType(int(input["entityType"])),
input["location"] if "location" in input else None,
server,
)
self._scheduled_events.add_scheduled_event(scheduled_event)
self._db.save_changes()
def get_new_scheduled_event(srn: ScheduledEvent):
return (
srn.interval == scheduled_event.interval
and srn.name == scheduled_event.name
and srn.description == scheduled_event.description
)
return (
self._scheduled_events.get_scheduled_events_by_server_id(scheduled_event.server.id)
.where(get_new_scheduled_event)
.last()
)
def resolve_update_scheduled_event(self, *_, input: dict):
scheduled_event = self._scheduled_events.get_scheduled_event_by_id(input["id"])
self._can_user_mutate_data(scheduled_event.server, UserRoleEnum.moderator)
scheduled_event.interval = (
ScheduledEventIntervalEnum(input["interval"]) if "interval" in input else scheduled_event.interval
)
scheduled_event.name = input["name"] if "name" in input else scheduled_event.name
scheduled_event.description = input["description"] if "description" in input else scheduled_event.description
scheduled_event.channel_id = input["channelId"] if "channelId" in input else scheduled_event.channel_id
scheduled_event.start_time = (
datetime.strptime(input["startTime"], "%Y-%m-%dT%H:%M:%S.%fZ")
if "startTime" in input
else scheduled_event.start_time
)
scheduled_event.end_time = (
datetime.strptime(input["endTime"], "%Y-%m-%dT%H:%M:%S.%fZ")
if "endTime" in input
else scheduled_event.end_time
)
scheduled_event.entity_type = (
EntityType(int(input["entityType"])) if "entityType" in input else scheduled_event.entity_type
)
scheduled_event.location = input["location"] if "location" in input else scheduled_event.location
self._scheduled_events.update_scheduled_event(scheduled_event)
self._db.save_changes()
scheduled_event = self._scheduled_events.get_scheduled_event_by_id(input["id"])
return scheduled_event
def resolve_delete_scheduled_event(self, *_, id: int):
scheduled_event = self._scheduled_events.get_scheduled_event_by_id(id)
self._can_user_mutate_data(scheduled_event.server, UserRoleEnum.admin)
self._scheduled_events.delete_scheduled_event(scheduled_event)
self._db.save_changes()
return scheduled_event

View File

@ -1,94 +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_core.service.permission_service import PermissionService
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
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 self._permissions.is_member_moderator(member) or 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)
if "author" not in warning:
author = Route.get_user().users.where(lambda u: u.server.id == user.server.id).single()
else:
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,17 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from bot_data.model.level_history import LevelHistory
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class LevelQuery(DataQueryWithHistoryABC):
def __init__(self, db: DatabaseContextABC):
DataQueryWithHistoryABC.__init__(self, "Level", "LevelsHistory", LevelHistory, db)
self.set_field("id", lambda x, *_: x.id)
self.set_field("iconURL", lambda x, *_: x.icon_url)
self.set_field("name", lambda x, *_: x.name)
self.set_field("color", lambda x, *_: x.color)
self.set_field("minXp", lambda x, *_: x.min_xp)
self.set_field("permissions", lambda x, *_: x.permissions)
self.set_field("server", lambda x, *_: x.server)

View File

@ -1,24 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from bot_data.model.scheduled_event_history import ScheduledEventHistory
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class ScheduledEventHistoryQuery(DataQueryWithHistoryABC):
def __init__(
self,
db: DatabaseContextABC,
):
DataQueryWithHistoryABC.__init__(self, "ScheduledEvent", "ScheduledEventsHistory", ScheduledEventHistory, db)
self.set_field("id", lambda x, *_: x.id)
self.set_field("id", lambda x, *_: x.id)
self.set_field("interval", lambda x, *_: x.interval.value)
self.set_field("name", lambda x, *_: x.name)
self.set_field("description", lambda x, *_: x.description)
self.set_field("channel_id", lambda x, *_: x.channel_id)
self.set_field("start_time", lambda x, *_: x.start_time)
self.set_field("end_time", lambda x, *_: x.end_time)
self.set_field("entity_type", lambda x, *_: x.entity_type)
self.set_field("location", lambda x, *_: x.location)
self.set_field("server", lambda x, *_: x.server)

View File

@ -1,23 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from bot_data.model.scheduled_event_history import ScheduledEventHistory
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class ScheduledEventQuery(DataQueryWithHistoryABC):
def __init__(
self,
db: DatabaseContextABC,
):
DataQueryWithHistoryABC.__init__(self, "ScheduledEvent", "ScheduledEventsHistory", ScheduledEventHistory, db)
self.set_field("id", lambda x, *_: x.id)
self.set_field("interval", lambda x, *_: x.interval.value)
self.set_field("name", lambda x, *_: x.name)
self.set_field("description", lambda x, *_: x.description)
self.set_field("channelId", lambda x, *_: x.channel_id)
self.set_field("startTime", lambda x, *_: x.start_time)
self.set_field("endTime", lambda x, *_: x.end_time)
self.set_field("entityType", lambda x, *_: x.entity_type.value)
self.set_field("location", lambda x, *_: x.location)
self.set_field("server", lambda x, *_: x.server)

View File

@ -1,179 +0,0 @@
import datetime
from typing import Optional
from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC
from cpl_core.type import R, T
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_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,
db: DatabaseContextABC,
):
QueryABC.__init__(self, "ServerStatistic")
self._config = config
self._db = db
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_user_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_active_user_count(self, server, *_):
return self._users.get_users_by_server_id(server.server.id).where(lambda x: not x.left_server).count()
def _cast_query_result(self, query: str, r_type: T) -> Optional[R]:
results = self._db.select(query)
if len(results) == 0 or len(results[0]) == 0:
return None
result = results[0][0]
default = None
if r_type is int or r_type is float:
default = 0
elif r_type is str:
default = ""
return r_type(result) if result is not None else default
def _resolve_achievements(self, server, *_):
query = f"""
SELECT Count(UserGotAchievements.CreatedAt) FROM UserGotAchievements
INNER JOIN Achievements ON UserGotAchievements.AchievementId = Achievements.Id
INNER JOIN Users ON UserGotAchievements.UserId = Users.UserId
WHERE Users.ServerId = {server.server.id}
AND UserGotAchievements.CreatedAt >= "{self._get_date(**server.kwargs)}";
"""
return self._cast_query_result(query, int)
def _resolve_message_count(self, server, *_):
query = f"""
SELECT SUM(
UserMessageCountPerHour.XPCount / (
SELECT XpPerMessage
FROM CFG_Server
WHERE ServerId = {server.server.id}
)
)
FROM UserMessageCountPerHour
INNER JOIN Users ON UserMessageCountPerHour.UserId = Users.UserId
WHERE Users.ServerId = {server.server.id}
AND UserMessageCountPerHour.CreatedAt >= "{self._get_date(**server.kwargs)}";
"""
return self._cast_query_result(query, int)
def _resolve_voice_channel_count(self, server, *_):
query = f"""
SELECT Count(UserJoinedVoiceChannel.CreatedAt) FROM UserJoinedVoiceChannel
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
WHERE Users.ServerId = {server.server.id}
AND UserJoinedVoiceChannel.CreatedAt >= "{self._get_date(**server.kwargs)}";
"""
return self._cast_query_result(query, int)
def _resolve_voice_channel_ontime(self, server, *_):
query = f"""
SELECT IFNULL(ROUND(SUM(
TIME_TO_SEC(TIMEDIFF(UserJoinedVoiceChannel.LeavedOn, UserJoinedVoiceChannel.JoinedOn)) / 3600
), 2), 0) FROM UserJoinedVoiceChannel
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
WHERE Users.ServerId = {server.server.id}
AND UserJoinedVoiceChannel.CreatedAt >= "{self._get_date(**server.kwargs)}";
"""
return self._cast_query_result(query, float)
def _resolve_game_server_count(self, server, *_):
query = f"""
SELECT Count(UserJoinedGameServer.CreatedAt) FROM UserJoinedGameServer
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
WHERE Users.ServerId = {server.server.id}
AND UserJoinedGameServer.CreatedAt >= "{self._get_date(**server.kwargs)}";
"""
return self._cast_query_result(query, int)
def _resolve_game_server_ontime(self, server, *_):
query = f"""
SELECT IFNULL(ROUND(SUM(
TIME_TO_SEC(TIMEDIFF(UserJoinedGameServer.LeavedOn, UserJoinedGameServer.JoinedOn)) / 3600
), 2), 0)
FROM UserJoinedGameServer
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
WHERE Users.ServerId = {server.server.id}
AND UserJoinedGameServer.CreatedAt >= "{self._get_date(**server.kwargs)}";
"""
return self._cast_query_result(query, float)
def _resolve_user_warning_count(self, server, *_):
query = f"""
SELECT COUNT(UserWarnings.CreatedAt) FROM UserWarnings
INNER JOIN Users ON UserWarnings.UserId = Users.UserId
WHERE Users.ServerId = {server.server.id}
AND UserWarnings.CreatedAt >= "{self._get_date(**server.kwargs)}";
"""
return self._cast_query_result(query, int)
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_user_count(server, *_)
)
/ days
* 1000
)
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 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,55 +0,0 @@
from cpl_core.configuration import ConfigurationABC
from cpl_discord.command import DiscordCommandABC
from cpl_translation import TranslatePipe
from discord.ext import commands
from discord.ext.commands import Context
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.helper.command_checks import CommandChecks
from bot_core.logging.command_logger import CommandLogger
from bot_core.service.message_service import MessageService
from bot_data.model.server_config import ServerConfig
from modules.base.service.event_service import EventService
class ScheduledEventsCommand(DiscordCommandABC):
def __init__(
self,
config: ConfigurationABC,
logger: CommandLogger,
events: EventService,
message_service: MessageService,
t: TranslatePipe,
):
DiscordCommandABC.__init__(self)
self._config = config
self._logger = logger
self._events = events
self._message_service = message_service
self._t = t
self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}")
@commands.hybrid_group(name="scheduled-events")
@commands.guild_only()
async def scheduled_events(self, ctx: Context):
pass
@scheduled_events.command()
@commands.guild_only()
@CommandChecks.check_is_ready()
@CommandChecks.check_is_member_moderator()
async def reload(self, ctx: Context):
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{ctx.guild.id}")
if not FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum.scheduled_events):
self._logger.debug(__name__, f"Skipping scheduled event check for {ctx.guild.id}. Feature is disabled.")
await self._message_service.send_ctx_msg(ctx, self._t.transform("common.feature_not_activated"))
return
self._logger.debug(__name__, "Running scheduled-events reload")
try:
await self._events.check_and_create_scheduled_events(ctx.guild)
except Exception as e:
self._logger.error(__name__, f"Reloading scheduled events failed", e)

View File

@ -1,147 +0,0 @@
import calendar
from datetime import datetime, timedelta
from typing import Optional
from zoneinfo import ZoneInfo
import discord
from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC
from cpl_core.logging import LoggerABC
from cpl_discord.container import Guild
from cpl_query.extension import List
from discord import PrivacyLevel, EventStatus
from discord.scheduled_event import ScheduledEvent as DiscordEvent
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.user_repository_abc import UserRepositoryABC
from bot_data.model.scheduled_event import ScheduledEvent
from bot_data.model.scheduled_event_interval_enum import ScheduledEventIntervalEnum
from bot_data.model.server_config import ServerConfig
from modules.base.model.active_event import ActiveEvent
class EventService:
def __init__(
self,
config: ConfigurationABC,
logger: LoggerABC,
servers: ServerRepositoryABC,
users: UserRepositoryABC,
db: DatabaseContextABC,
events: ScheduledEventRepositoryABC,
):
self._config = config
self._logger = logger
self._servers = servers
self._users = users
self._db = db
self._events = events
self._active_events = List(ActiveEvent)
def add_event(self, event: ActiveEvent):
if self._active_events.contains(event):
return
self._active_events.add(event)
def get_active_event(self, event: discord.ScheduledEvent) -> Optional[ActiveEvent]:
return self._active_events.where(lambda x: x.event.id == event.id).single_or_default()
def get_active_event_by_channel_id(self, channel_id: int) -> Optional[ActiveEvent]:
return self._active_events.where(
lambda x: x.event.channel is not None and x.event.channel.id == channel_id
).single_or_default()
def remove_event(self, event: ActiveEvent):
if not self._active_events.contains(event):
return
self._active_events.remove(event)
def give_xp_for_event_participation(self, member: discord.Member, active_event: ActiveEvent):
server = self._servers.get_server_by_discord_id(member.guild.id)
user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id)
if active_event.participants.any(lambda x: x.id == user.id):
self._logger.debug(__name__, f"Module {type(self)} stopped")
return
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.discord_id}")
user.xp += settings.xp_per_event_participation
self._users.update_user(user)
self._db.save_changes()
active_event.participants.append(user)
def _append_interval(self, interval: ScheduledEventIntervalEnum, ts: datetime) -> datetime:
now = datetime.now().replace(tzinfo=ZoneInfo("Europe/Berlin"))
if ts >= now:
return ts
if interval == ScheduledEventIntervalEnum.daily:
ts = ts + timedelta(days=1)
elif interval == ScheduledEventIntervalEnum.weekly:
ts = ts + timedelta(weeks=1)
elif interval == ScheduledEventIntervalEnum.monthly:
days_in_month = calendar.monthrange(ts.year, ts.month + 1)[1]
ts = ts + timedelta(days=days_in_month)
elif interval == ScheduledEventIntervalEnum.yearly:
ts = ts + timedelta(days=365)
while ts < now:
ts = self._append_interval(interval, ts)
return ts
async def check_and_create_scheduled_events(self, guild: Guild):
server = self._servers.get_server_by_discord_id(guild.id)
scheduled_events_from_db = self._events.get_scheduled_events_by_server_id(server.id)
self._logger.debug(__name__, f"Checking {scheduled_events_from_db.count()} events for server {guild.id}")
for scheduled_event in scheduled_events_from_db:
scheduled_event: ScheduledEvent = scheduled_event
from_guild = List(DiscordEvent, guild.scheduled_events).where(
lambda x: x.name == scheduled_event.name
and x.description == scheduled_event.description
and x.entity_type == scheduled_event.entity_type
and x.status == EventStatus.scheduled
)
if from_guild.count() != 0:
self._logger.debug(__name__, f"Event {scheduled_event.name} already exists on discord server")
continue
kwargs = {"name": scheduled_event.name, "description": scheduled_event.description}
if scheduled_event.channel_id is not None:
kwargs["channel"] = guild.get_channel(scheduled_event.channel_id)
if scheduled_event.start_time is not None:
start_time = self._append_interval(
scheduled_event.interval, scheduled_event.start_time.replace(tzinfo=ZoneInfo("Europe/Berlin"))
)
kwargs["start_time"] = start_time
scheduled_event.start_time = start_time.replace(tzinfo=None)
if scheduled_event.end_time is not None:
end_time = self._append_interval(
scheduled_event.interval, scheduled_event.end_time.replace(tzinfo=ZoneInfo("Europe/Berlin"))
)
kwargs["end_time"] = end_time
scheduled_event.end_time = end_time.replace(tzinfo=None)
kwargs["entity_type"] = scheduled_event.entity_type
if scheduled_event.location is not None:
kwargs["location"] = scheduled_event.location
kwargs["privacy_level"] = PrivacyLevel.guild_only
try:
self._logger.trace(__name__, f"Try to create scheduled event for guild {guild.name}")
await guild.create_scheduled_event(**kwargs)
self._events.update_scheduled_event(scheduled_event)
self._db.save_changes()
self._logger.debug(__name__, f"Created scheduled event for guild {guild.name}")
except Exception as e:
self._logger.error(__name__, f"Watching scheduled events failed", e)

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.base.tasks"
__author__ = "Sven Heidemann"
__license__ = "MIT"
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
__version__ = "1.2.8"
from collections import namedtuple
# imports:
VersionInfo = namedtuple("VersionInfo", "major minor micro")
version_info = VersionInfo(major="1", minor="2", micro="8")

View File

@ -1,68 +0,0 @@
import datetime
from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC
from cpl_translation import TranslatePipe
from discord.ext import tasks
from bot_core.abc.task_abc import TaskABC
from bot_core.logging.task_logger import TaskLogger
from bot_core.service.message_service import MessageService
from bot_data.abc.user_repository_abc import UserRepositoryABC
from bot_data.model.server_config import ServerConfig
class BirthdayWatcher(TaskABC):
def __init__(
self,
config: ConfigurationABC,
logger: TaskLogger,
bot: DiscordBotServiceABC,
db: DatabaseContextABC,
users: UserRepositoryABC,
message_service: MessageService,
t: TranslatePipe,
):
TaskABC.__init__(self)
self._config = config
self._logger = logger
self._bot = bot
self._db = db
self._users = users
self._message_service = message_service
self._t = t
if not self._is_maintenance():
self.watch.start()
@tasks.loop(time=datetime.time(hour=8, minute=0), reconnect=True)
async def watch(self):
self._logger.info(__name__, "Watching birthdays")
try:
today = datetime.date.today()
users = self._users.get_users().where(lambda x: x.birthday is not None)
for user in users:
if user.birthday.day != today.day or user.birthday.month != today.month:
continue
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{user.server.discord_id}")
user.xp += settings.xp_for_birthday
self._users.update_user(user)
self._db.save_changes()
guild = self._bot.get_guild(user.server.discord_id)
member = guild.get_member(user.discord_id)
await self._message_service.send_channel_message(
self._bot.get_channel(settings.notification_chat_id),
self._t.transform("modules.base.user.birthday.has_birthday").format(member.mention),
is_persistent=True,
)
except Exception as e:
self._logger.error(__name__, f"Watching birthdays failed", e)
@watch.before_loop
async def wait(self):
await self._wait_until_ready()

View File

@ -1,61 +0,0 @@
from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC
from cpl_translation import TranslatePipe
from discord.ext import tasks
from bot_core.abc.task_abc import TaskABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_core.logging.task_logger import TaskLogger
from bot_core.service.message_service import MessageService
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.model.server_config import ServerConfig
from modules.base.service.event_service import EventService
class ScheduledEventsWatcher(TaskABC):
def __init__(
self,
config: ConfigurationABC,
logger: TaskLogger,
bot: DiscordBotServiceABC,
db: DatabaseContextABC,
servers: ServerRepositoryABC,
events: EventService,
message_service: MessageService,
t: TranslatePipe,
):
TaskABC.__init__(self)
self._config = config
self._logger = logger
self._bot = bot
self._db = db
self._servers = servers
self._events = events
self._message_service = message_service
self._t = t
if not self._is_maintenance():
self.watch.start()
@tasks.loop(hours=3, reconnect=True)
async def watch(self):
self._logger.info(__name__, "Watching scheduled events")
try:
for guild in self._bot.guilds:
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
if not FeatureFlagsSettings.get_flag_from_dict(
settings.feature_flags, FeatureFlagsEnum.scheduled_events
):
self._logger.debug(__name__, f"Skipping scheduled event check for {guild.id}. Feature is disabled.")
continue
await self._events.check_and_create_scheduled_events(guild)
except Exception as e:
self._logger.error(__name__, f"Watching scheduled events failed", e)
@watch.before_loop
async def wait(self):
await self._wait_until_ready()

View File

@ -1,31 +0,0 @@
{
"DefaultLevel": {
"LevelHeader": "~~~ dev-Level ~~~",
"Levels": [
{
"Name": "dev-Newbie",
"Color": "0x1abc9c",
"MinXp": 0,
"Permissions": 968552209984
},
{
"Name": "dev-Keks",
"Color": "0x2ecc71",
"MinXp": 100,
"Permissions": 1002928856640
},
{
"Name": "dev-Doppelkeks",
"Color": "0x3498db",
"MinXp": 200,
"Permissions": 1071849660224
},
{
"Name": "dev-Auror",
"Color": "0xf1c40f",
"MinXp": 300,
"Permissions": 1089042120513
}
]
}
}

View File

@ -1,31 +0,0 @@
{
"DefaultLevel": {
"LevelHeader": "~~~ ed-Level ~~~",
"Levels": [
{
"Name": "ed-Newbie",
"Color": "0x1abc9c",
"MinXp": 0,
"Permissions": 968552209984
},
{
"Name": "ed-Keks",
"Color": "0x2ecc71",
"MinXp": 100,
"Permissions": 1002928856640
},
{
"Name": "ed-Doppelkeks",
"Color": "0x3498db",
"MinXp": 200,
"Permissions": 1071849660224
},
{
"Name": "ed-Auror",
"Color": "0xf1c40f",
"MinXp": 300,
"Permissions": 1089042120513
}
]
}
}

View File

@ -1,31 +0,0 @@
{
"DefaultLevel": {
"LevelHeader": "~~~ ed-Level ~~~",
"Levels": [
{
"Name": "ed-Newbie",
"Color": "0x1abc9c",
"MinXp": 0,
"Permissions": 968552209984
},
{
"Name": "ed-Keks",
"Color": "0x2ecc71",
"MinXp": 100,
"Permissions": 1002928856640
},
{
"Name": "ed-Doppelkeks",
"Color": "0x3498db",
"MinXp": 200,
"Permissions": 1071849660224
},
{
"Name": "ed-Auror",
"Color": "0xf1c40f",
"MinXp": 300,
"Permissions": 1089042120513
}
]
}
}

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