Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
069c701a05 | |||
5efcddf983 | |||
5beaf24bdc | |||
4bbcd387c6 | |||
117e1aeda8 | |||
7260ed0164 | |||
77d723b9da | |||
75c316f2d2 | |||
de78cec96c | |||
9de66d4fd4 |
@@ -1,17 +0,0 @@
|
|||||||
#### Beschreibung
|
|
||||||
|
|
||||||
Als Produktmanager muss ich nun dieses Ticket ausfüllen.
|
|
||||||
|
|
||||||
#### Aktuelles Verhalten
|
|
||||||
|
|
||||||
* Was macht die Software aktuell?
|
|
||||||
|
|
||||||
#### Gewünschtes Verhalten
|
|
||||||
|
|
||||||
* Was soll die Software anders machen?
|
|
||||||
|
|
||||||
#### Akzeptanzkriterien
|
|
||||||
|
|
||||||
* Was muss erfüllt sein, damit das Ticket als abgeschlossen angesehen werden kann?
|
|
||||||
|
|
||||||
#### Anmerkungen
|
|
@@ -1,7 +0,0 @@
|
|||||||
#### Ticket Referenz:
|
|
||||||
|
|
||||||
#1
|
|
||||||
|
|
||||||
#### Gibt es etwas beim Review zu beachten?
|
|
||||||
|
|
||||||
Nein
|
|
@@ -1,71 +0,0 @@
|
|||||||
name: Deploy dev on push
|
|
||||||
run-name: Deploy dev on push
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
on-push-deploy_sh-edraft:
|
|
||||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
|
||||||
container: sh-edraft.de/act-runner:latest
|
|
||||||
steps:
|
|
||||||
- name: Setup docker
|
|
||||||
uses: https://github.com/papodaca/install-docker-action@main
|
|
||||||
- run: docker -v
|
|
||||||
|
|
||||||
- name: Clone Repository
|
|
||||||
uses: https://github.com/actions/checkout@v3
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
|
||||||
submodules: true
|
|
||||||
|
|
||||||
- name: Prepare bot build
|
|
||||||
run: |
|
|
||||||
cd bot
|
|
||||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
|
||||||
cpl i
|
|
||||||
|
|
||||||
- name: Setup node
|
|
||||||
uses: https://github.com/actions/setup-node@v3
|
|
||||||
|
|
||||||
- name: Prepare web build
|
|
||||||
run: |
|
|
||||||
cd web
|
|
||||||
npm install -g ts-node
|
|
||||||
npm ci
|
|
||||||
|
|
||||||
- name: Shutdown stack
|
|
||||||
run: docker stack rm sdb_dev
|
|
||||||
|
|
||||||
- name: Build docker bot
|
|
||||||
run: |
|
|
||||||
cd bot
|
|
||||||
docker image prune -f
|
|
||||||
cpl build
|
|
||||||
docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-dev .
|
|
||||||
|
|
||||||
- name: Build docker web
|
|
||||||
run: |
|
|
||||||
cd web
|
|
||||||
docker image prune -f
|
|
||||||
cp src/favicon.dev.ico src/favicon.ico
|
|
||||||
npm run build
|
|
||||||
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-dev .
|
|
||||||
|
|
||||||
- name: Set version
|
|
||||||
run: |
|
|
||||||
cd bot/docker
|
|
||||||
chmod +x ./set-docker-compose-image-version.sh
|
|
||||||
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-dev sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-dev
|
|
||||||
|
|
||||||
- name: Deploy Stack to sh-edraft.de
|
|
||||||
uses: https://github.com/kgierke/portainer-stack-deployment@v1
|
|
||||||
with:
|
|
||||||
portainer-url: "https://docker.sh-edraft.de"
|
|
||||||
portainer-username: "gitea_job"
|
|
||||||
portainer-password: "${{ secrets.docker_job }}"
|
|
||||||
portainer-endpoint: 2
|
|
||||||
name: sdb_dev
|
|
||||||
file: bot/docker/docker-compose.dev.yml
|
|
||||||
variables: '{}'
|
|
@@ -1,70 +0,0 @@
|
|||||||
name: Deploy prod on push
|
|
||||||
run-name: Deploy prod on push
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
on-push-deploy_sh-edraft:
|
|
||||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
|
||||||
container: sh-edraft.de/act-runner:latest
|
|
||||||
steps:
|
|
||||||
- name: Setup docker
|
|
||||||
uses: https://github.com/papodaca/install-docker-action@main
|
|
||||||
- run: docker -v
|
|
||||||
|
|
||||||
- name: Clone Repository
|
|
||||||
uses: https://github.com/actions/checkout@v3
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
|
||||||
submodules: true
|
|
||||||
|
|
||||||
- name: Prepare bot build
|
|
||||||
run: |
|
|
||||||
cd bot
|
|
||||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
|
||||||
cpl i
|
|
||||||
|
|
||||||
- name: Setup node
|
|
||||||
uses: https://github.com/actions/setup-node@v3
|
|
||||||
|
|
||||||
- name: Prepare web build
|
|
||||||
run: |
|
|
||||||
cd web
|
|
||||||
npm install -g ts-node
|
|
||||||
npm ci
|
|
||||||
|
|
||||||
- name: Shutdown stack
|
|
||||||
run: docker stack rm sdb_prod
|
|
||||||
|
|
||||||
- name: Build docker bot
|
|
||||||
run: |
|
|
||||||
cd bot
|
|
||||||
docker image prune -f
|
|
||||||
cpl build
|
|
||||||
docker build -t sh-edraft.de/sdb-bot:$(cpl gv) .
|
|
||||||
|
|
||||||
- name: Build docker web
|
|
||||||
run: |
|
|
||||||
cd web
|
|
||||||
docker image prune -f
|
|
||||||
npm run build
|
|
||||||
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv) .
|
|
||||||
|
|
||||||
- name: Set version
|
|
||||||
run: |
|
|
||||||
cd bot/docker
|
|
||||||
chmod +x ./set-docker-compose-image-version.sh
|
|
||||||
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv) sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)
|
|
||||||
|
|
||||||
- name: Deploy Stack to sh-edraft.de
|
|
||||||
uses: https://github.com/kgierke/portainer-stack-deployment@v1
|
|
||||||
with:
|
|
||||||
portainer-url: "https://docker.sh-edraft.de"
|
|
||||||
portainer-username: "gitea_job"
|
|
||||||
portainer-password: "${{ secrets.docker_job }}"
|
|
||||||
portainer-endpoint: 2
|
|
||||||
name: sdb_prod
|
|
||||||
file: bot/docker/docker-compose.yml
|
|
||||||
variables: '{}'
|
|
@@ -1,71 +0,0 @@
|
|||||||
name: Deploy staging on push
|
|
||||||
run-name: Deploy staging on push
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- staging
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
on-push-deploy_sh-edraft:
|
|
||||||
runs-on: [ dobby.sh-edraft.de, ubuntu-latest ]
|
|
||||||
container: sh-edraft.de/act-runner:latest
|
|
||||||
steps:
|
|
||||||
- name: Setup docker
|
|
||||||
uses: https://github.com/papodaca/install-docker-action@main
|
|
||||||
- run: docker -v
|
|
||||||
|
|
||||||
- name: Clone Repository
|
|
||||||
uses: https://github.com/actions/checkout@v3
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CI_ACCESS_TOKEN }}
|
|
||||||
submodules: true
|
|
||||||
|
|
||||||
- name: Prepare bot build
|
|
||||||
run: |
|
|
||||||
cd bot
|
|
||||||
python3.10 -m pip install --extra-index-url https://pip.sh-edraft.de cpl-cli
|
|
||||||
cpl i
|
|
||||||
|
|
||||||
- name: Setup node
|
|
||||||
uses: https://github.com/actions/setup-node@v3
|
|
||||||
|
|
||||||
- name: Prepare web build
|
|
||||||
run: |
|
|
||||||
cd web
|
|
||||||
npm install -g ts-node
|
|
||||||
npm ci
|
|
||||||
|
|
||||||
- name: Shutdown stack
|
|
||||||
run: docker stack rm sdb_staging
|
|
||||||
|
|
||||||
- name: Build docker bot
|
|
||||||
run: |
|
|
||||||
cd bot
|
|
||||||
docker image prune -f
|
|
||||||
cpl build
|
|
||||||
docker build -t sh-edraft.de/sdb-bot:$(cpl gv)-staging .
|
|
||||||
|
|
||||||
- name: Build docker web
|
|
||||||
run: |
|
|
||||||
cd web
|
|
||||||
docker image prune -f
|
|
||||||
cp src/favicon.staging.ico src/favicon.ico
|
|
||||||
npm run build
|
|
||||||
docker build -t sh-edraft.de/sdb-web:$(npm run -s gv)-staging .
|
|
||||||
|
|
||||||
- name: Set version
|
|
||||||
run: |
|
|
||||||
cd bot/docker
|
|
||||||
chmod +x ./set-docker-compose-image-version.sh
|
|
||||||
./set-docker-compose-image-version.sh sh-edraft.de/sdb-bot:$(cd ../; cpl gv)-staging sh-edraft.de/sdb-web:$(cd ../../web; npm run -s gv;)-staging
|
|
||||||
|
|
||||||
- name: Deploy Stack to sh-edraft.de
|
|
||||||
uses: https://github.com/kgierke/portainer-stack-deployment@v1
|
|
||||||
with:
|
|
||||||
portainer-url: "https://docker.sh-edraft.de"
|
|
||||||
portainer-username: "gitea_job"
|
|
||||||
portainer-password: "${{ secrets.docker_job }}"
|
|
||||||
portainer-endpoint: 2
|
|
||||||
name: sdb_staging
|
|
||||||
file: bot/docker/docker-compose.staging.yml
|
|
||||||
variables: '{}'
|
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -144,3 +144,4 @@ deploy/
|
|||||||
|
|
||||||
# idea
|
# idea
|
||||||
.idea/
|
.idea/
|
||||||
|
selenium-data/
|
18
.gitmodules
vendored
18
.gitmodules
vendored
@@ -1,9 +1,9 @@
|
|||||||
[submodule "bot/src/bot/config"]
|
[submodule "kdb-bot/src/bot/config"]
|
||||||
path = bot/src/bot/config
|
path = kdb-bot/src/bot/config
|
||||||
url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.config.git
|
url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.config.git
|
||||||
[submodule "bot/src/bot_api/config"]
|
[submodule "kdb-bot/src/bot_api/config"]
|
||||||
path = bot/src/bot_api/config
|
path = kdb-bot/src/bot_api/config
|
||||||
url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.api.config.git
|
url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.api.config.git
|
||||||
[submodule "bot/docker"]
|
[submodule "kdb-bot/docker"]
|
||||||
path = bot/docker
|
path = kdb-bot/docker
|
||||||
url = https://git.sh-edraft.de/sh-edraft.de/sh_discord_bot.docker.git
|
url = https://git.sh-edraft.de/sh-edraft.de/kd_discord_bot.docker.git
|
||||||
|
9
LICENSE
9
LICENSE
@@ -1,9 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2022-2023 sh-edraft.de
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
@@ -1,100 +0,0 @@
|
|||||||
from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC
|
|
||||||
|
|
||||||
|
|
||||||
class DBTable(GenerateSchematicABC):
|
|
||||||
def __init__(self, *args: str):
|
|
||||||
GenerateSchematicABC.__init__(self, *args)
|
|
||||||
self._name = self._name.replace("_db_table", "")
|
|
||||||
self._class_name = self._class_name.split("Db_table")[0]
|
|
||||||
|
|
||||||
def get_code(self) -> str:
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
code = textwrap.dedent(
|
|
||||||
"""\
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from cpl_core.database import TableABC
|
|
||||||
|
|
||||||
|
|
||||||
class $ClassName(TableABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
value: str,
|
|
||||||
created_at: datetime = None,
|
|
||||||
modified_at: datetime = None,
|
|
||||||
id=0,
|
|
||||||
):
|
|
||||||
self._id = id
|
|
||||||
self._value = value
|
|
||||||
|
|
||||||
TableABC.__init__(self)
|
|
||||||
self._created_at = created_at if created_at is not None else self._created_at
|
|
||||||
self._modified_at = modified_at if modified_at is not None else self._modified_at
|
|
||||||
|
|
||||||
@property
|
|
||||||
def value(self) -> str:
|
|
||||||
return self._value
|
|
||||||
|
|
||||||
@value.setter
|
|
||||||
def value(self, value: str):
|
|
||||||
self._value = value
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_select_all_string() -> str:
|
|
||||||
return str(
|
|
||||||
f\"""
|
|
||||||
SELECT * FROM `$TableName`;
|
|
||||||
\"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_select_by_id_string(id: int) -> str:
|
|
||||||
return str(
|
|
||||||
f\"""
|
|
||||||
SELECT * FROM `$TableName`
|
|
||||||
WHERE `Id` = {id};
|
|
||||||
\"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def insert_string(self) -> str:
|
|
||||||
return str(
|
|
||||||
f\"""
|
|
||||||
INSERT INTO `$TableName` (
|
|
||||||
`Value`
|
|
||||||
) VALUES (
|
|
||||||
{self._value}
|
|
||||||
);
|
|
||||||
\"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def udpate_string(self) -> str:
|
|
||||||
return str(
|
|
||||||
f\"""
|
|
||||||
UPDATE `$TableName`
|
|
||||||
SET `Value` = {self._value}
|
|
||||||
WHERE `Id` = {self._id};
|
|
||||||
\"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def delete_string(self) -> str:
|
|
||||||
return str(
|
|
||||||
f\"""
|
|
||||||
DELETE FROM `$TableName`
|
|
||||||
WHERE `Id` = {self._id};
|
|
||||||
\"""
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
return self.build_code_str(
|
|
||||||
code,
|
|
||||||
ClassName=self._class_name,
|
|
||||||
TableName=self._class_name,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register(cls):
|
|
||||||
GenerateSchematicABC.register(cls, "db-table", [])
|
|
@@ -1,55 +0,0 @@
|
|||||||
from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(GenerateSchematicABC):
|
|
||||||
def __init__(self, *args: str):
|
|
||||||
GenerateSchematicABC.__init__(self, *args)
|
|
||||||
|
|
||||||
def get_code(self) -> str:
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
code = textwrap.dedent(
|
|
||||||
"""\
|
|
||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class $ClassName(MigrationABC):
|
|
||||||
name = "1.0_$ClassName"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._cursor = db.cursor
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f\"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `$TableName` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`CreatedAt` DATETIME(6),
|
|
||||||
`LastModifiedAt` DATETIME(6),
|
|
||||||
PRIMARY KEY(`Id`)
|
|
||||||
);
|
|
||||||
\"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._cursor.execute("DROP TABLE `$TableName`;")
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
return self.build_code_str(
|
|
||||||
code,
|
|
||||||
ClassName=self._class_name,
|
|
||||||
TableName=self._class_name.split("Migration")[0],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register(cls):
|
|
||||||
GenerateSchematicABC.register(cls, "migration", [])
|
|
@@ -1,34 +0,0 @@
|
|||||||
from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC
|
|
||||||
|
|
||||||
|
|
||||||
class Query(GenerateSchematicABC):
|
|
||||||
def __init__(self, *args: str):
|
|
||||||
GenerateSchematicABC.__init__(self, *args)
|
|
||||||
|
|
||||||
def get_code(self) -> str:
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
code = textwrap.dedent(
|
|
||||||
"""\
|
|
||||||
from bot_graphql.abc.data_query_abc import DataQueryABC
|
|
||||||
|
|
||||||
|
|
||||||
class $ClassName(DataQueryABC):
|
|
||||||
def __init__(self):
|
|
||||||
DataQueryABC.__init__(self, "Name")
|
|
||||||
|
|
||||||
self.set_field("id", self.resolve_id)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_id(x, *_):
|
|
||||||
return x.id
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
return self.build_code_str(
|
|
||||||
code,
|
|
||||||
ClassName=self._class_name,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register(cls):
|
|
||||||
GenerateSchematicABC.register(cls, "query", [])
|
|
@@ -1,2 +0,0 @@
|
|||||||
# kd_discord_bot
|
|
||||||
|
|
Submodule bot/docker deleted from 9c0dc59534
@@ -1,2 +0,0 @@
|
|||||||
[tool.black]
|
|
||||||
line-length = 120
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
Submodule bot/src/bot/config deleted from c11ca6f2e8
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot.extension"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,16 +0,0 @@
|
|||||||
from cpl_core.application import ApplicationExtensionABC
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
|
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
|
||||||
|
|
||||||
|
|
||||||
class InitBotExtension(ApplicationExtensionABC):
|
|
||||||
def __init__(self):
|
|
||||||
ApplicationExtensionABC.__init__(self)
|
|
||||||
|
|
||||||
async def run(self, config: ConfigurationABC, services: ServiceProviderABC):
|
|
||||||
settings = config.get_configuration(TechnicianConfig)
|
|
||||||
|
|
||||||
bot: DiscordBotServiceABC = services.get_service(DiscordBotServiceABC, max_messages=settings.cache_max_messages)
|
|
@@ -1,46 +0,0 @@
|
|||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_api.api_module import ApiModule
|
|
||||||
from bot_core.core_extension.core_extension_module import CoreExtensionModule
|
|
||||||
from bot_core.core_module import CoreModule
|
|
||||||
from bot_data.data_module import DataModule
|
|
||||||
from bot_graphql.graphql_module import GraphQLModule
|
|
||||||
from modules.achievements.achievements_module import AchievementsModule
|
|
||||||
from modules.auto_role.auto_role_module import AutoRoleModule
|
|
||||||
from modules.base.base_module import BaseModule
|
|
||||||
from modules.boot_log.boot_log_module import BootLogModule
|
|
||||||
from modules.config.config_module import ConfigModule
|
|
||||||
from modules.database.database_module import DatabaseModule
|
|
||||||
from modules.level.level_module import LevelModule
|
|
||||||
from modules.permission.permission_module import PermissionModule
|
|
||||||
from modules.short_role_name.short_role_name_module import ShortRoleNameModule
|
|
||||||
from modules.special_offers.special_offers_module import SteamSpecialOffersModule
|
|
||||||
from modules.technician.technician_module import TechnicianModule
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleList:
|
|
||||||
@staticmethod
|
|
||||||
def get_modules():
|
|
||||||
# core modules (modules out of modules folder) should be loaded first!
|
|
||||||
return List(
|
|
||||||
type,
|
|
||||||
[
|
|
||||||
CoreModule, # has to be first!
|
|
||||||
DataModule,
|
|
||||||
ConfigModule, # has to be before db check
|
|
||||||
DatabaseModule,
|
|
||||||
GraphQLModule,
|
|
||||||
PermissionModule,
|
|
||||||
AutoRoleModule,
|
|
||||||
BaseModule,
|
|
||||||
LevelModule,
|
|
||||||
ApiModule,
|
|
||||||
TechnicianModule,
|
|
||||||
AchievementsModule,
|
|
||||||
ShortRoleNameModule,
|
|
||||||
SteamSpecialOffersModule,
|
|
||||||
# has to be last!
|
|
||||||
BootLogModule,
|
|
||||||
CoreExtensionModule,
|
|
||||||
],
|
|
||||||
)
|
|
@@ -1,55 +0,0 @@
|
|||||||
import os
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Optional, Type, Callable
|
|
||||||
|
|
||||||
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_core.configuration.bot_logging_settings import BotLoggingSettings
|
|
||||||
from bot_core.environment_variables import MAINTENANCE, MIGRATION_ONLY
|
|
||||||
|
|
||||||
|
|
||||||
class StartupSettingsExtension(StartupExtensionABC):
|
|
||||||
def __init__(self):
|
|
||||||
self._start_time = datetime.now()
|
|
||||||
|
|
||||||
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironmentABC):
|
|
||||||
# this shit has to be done here because we need settings in subsequent startup extensions
|
|
||||||
environment.set_working_directory(os.path.dirname(os.path.realpath(__file__)))
|
|
||||||
configuration.add_environment_variables("SDB_")
|
|
||||||
configuration.add_environment_variables("DISCORD_")
|
|
||||||
configuration.add_configuration(
|
|
||||||
MAINTENANCE, configuration.get_configuration(MAINTENANCE) in [True, "true", "True"]
|
|
||||||
)
|
|
||||||
configuration.add_configuration(
|
|
||||||
MIGRATION_ONLY, configuration.get_configuration(MIGRATION_ONLY) in [True, "true", "True"]
|
|
||||||
)
|
|
||||||
|
|
||||||
configuration.add_json_file(f"config/appsettings.json", optional=False)
|
|
||||||
configuration.add_json_file(f"config/appsettings.{environment.environment_name}.json", optional=True)
|
|
||||||
configuration.add_json_file(f"config/appsettings.{environment.host_name}.json", optional=True)
|
|
||||||
# load feature-flags
|
|
||||||
configuration.add_json_file(f"config/feature-flags.json", optional=False)
|
|
||||||
configuration.add_json_file(f"config/feature-flags.{environment.environment_name}.json", optional=True)
|
|
||||||
configuration.add_json_file(f"config/feature-flags.{environment.host_name}.json", optional=True)
|
|
||||||
|
|
||||||
configuration.add_configuration("Startup_StartTime", str(self._start_time))
|
|
||||||
self._configure_settings_with_sub_settings(
|
|
||||||
configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key
|
|
||||||
)
|
|
||||||
|
|
||||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _configure_settings_with_sub_settings(
|
|
||||||
config: ConfigurationABC, settings_type: Type, list_atr: Callable, atr: Callable
|
|
||||||
):
|
|
||||||
settings: Optional[settings_type] = config.get_configuration(settings_type)
|
|
||||||
if settings is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
for sub_settings in list_atr(settings):
|
|
||||||
config.add_configuration(f"{type(sub_settings).__name__}_{atr(sub_settings)}", sub_settings)
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.abc"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,15 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
|
|
||||||
class DtoABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def from_dict(self, values: dict):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
pass
|
|
@@ -1,26 +0,0 @@
|
|||||||
import threading
|
|
||||||
|
|
||||||
from bot_api.api import Api
|
|
||||||
from bot_api.logging.api_logger import ApiLogger
|
|
||||||
|
|
||||||
|
|
||||||
class ApiThread(threading.Thread):
|
|
||||||
def __init__(self, logger: ApiLogger, api: Api):
|
|
||||||
threading.Thread.__init__(self, daemon=True)
|
|
||||||
|
|
||||||
self._logger = logger
|
|
||||||
self._api = api
|
|
||||||
|
|
||||||
def run(self) -> None:
|
|
||||||
try:
|
|
||||||
self._logger.trace(__name__, f"Try to start {type(self._api).__name__}")
|
|
||||||
self._api.start()
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, "Start failed", e)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
try:
|
|
||||||
self._logger.trace(__name__, f"Try to stop {type(self._api).__name__}")
|
|
||||||
self._api.stop()
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, "Stop failed", e)
|
|
Submodule bot/src/bot_api/config deleted from 521951b8ab
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.configuration"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,22 +0,0 @@
|
|||||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
|
||||||
|
|
||||||
|
|
||||||
class ApiSettings(ConfigurationModelABC):
|
|
||||||
def __init__(self, port: int = None, host: str = None, redirect_uri: bool = None):
|
|
||||||
ConfigurationModelABC.__init__(self)
|
|
||||||
|
|
||||||
self._port = 80 if port is None else port
|
|
||||||
self._host = "" if host is None else host
|
|
||||||
self._redirect_to_https = False if redirect_uri is None else redirect_uri
|
|
||||||
|
|
||||||
@property
|
|
||||||
def port(self) -> int:
|
|
||||||
return self._port
|
|
||||||
|
|
||||||
@property
|
|
||||||
def host(self) -> str:
|
|
||||||
return self._host
|
|
||||||
|
|
||||||
@property
|
|
||||||
def redirect_to_https(self) -> bool:
|
|
||||||
return self._redirect_to_https
|
|
@@ -1,39 +0,0 @@
|
|||||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationSettings(ConfigurationModelABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
secret_key: str = None,
|
|
||||||
issuer: str = None,
|
|
||||||
audience: str = None,
|
|
||||||
token_expire_time: int = None,
|
|
||||||
refresh_token_expire_time: int = None,
|
|
||||||
):
|
|
||||||
ConfigurationModelABC.__init__(self)
|
|
||||||
|
|
||||||
self._secret_key = "" if secret_key is None else secret_key
|
|
||||||
self._issuer = "" if issuer is None else issuer
|
|
||||||
self._audience = "" if audience is None else audience
|
|
||||||
self._token_expire_time = 0 if token_expire_time is None else token_expire_time
|
|
||||||
self._refresh_token_expire_time = 0 if refresh_token_expire_time is None else refresh_token_expire_time
|
|
||||||
|
|
||||||
@property
|
|
||||||
def secret_key(self) -> str:
|
|
||||||
return self._secret_key
|
|
||||||
|
|
||||||
@property
|
|
||||||
def issuer(self) -> str:
|
|
||||||
return self._issuer
|
|
||||||
|
|
||||||
@property
|
|
||||||
def audience(self) -> str:
|
|
||||||
return self._audience
|
|
||||||
|
|
||||||
@property
|
|
||||||
def token_expire_time(self) -> int:
|
|
||||||
return self._token_expire_time
|
|
||||||
|
|
||||||
@property
|
|
||||||
def refresh_token_expire_time(self) -> int:
|
|
||||||
return self._refresh_token_expire_time
|
|
@@ -1,40 +0,0 @@
|
|||||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
|
|
||||||
class DiscordAuthenticationSettings(ConfigurationModelABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
client_secret: str = None,
|
|
||||||
redirect_uri: str = None,
|
|
||||||
scope: list = None,
|
|
||||||
token_url: str = None,
|
|
||||||
auth_url: str = None,
|
|
||||||
):
|
|
||||||
ConfigurationModelABC.__init__(self)
|
|
||||||
|
|
||||||
self._client_secret = "" if client_secret is None else client_secret
|
|
||||||
self._redirect_url = "" if redirect_uri is None else redirect_uri
|
|
||||||
self._scope = List() if scope is None else List(str, scope)
|
|
||||||
self._token_url = "" if token_url is None else token_url
|
|
||||||
self._auth_url = "" if auth_url is None else auth_url
|
|
||||||
|
|
||||||
@property
|
|
||||||
def client_secret(self) -> str:
|
|
||||||
return self._client_secret
|
|
||||||
|
|
||||||
@property
|
|
||||||
def redirect_url(self) -> str:
|
|
||||||
return self._redirect_url
|
|
||||||
|
|
||||||
@property
|
|
||||||
def scope(self) -> List[str]:
|
|
||||||
return self._scope
|
|
||||||
|
|
||||||
@property
|
|
||||||
def token_url(self) -> str:
|
|
||||||
return self._token_url
|
|
||||||
|
|
||||||
@property
|
|
||||||
def auth_url(self) -> str:
|
|
||||||
return self._auth_url
|
|
@@ -1,12 +0,0 @@
|
|||||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
|
||||||
|
|
||||||
|
|
||||||
class FrontendSettings(ConfigurationModelABC):
|
|
||||||
def __init__(self, url: str = None):
|
|
||||||
ConfigurationModelABC.__init__(self)
|
|
||||||
|
|
||||||
self._url = "" if url is None else url
|
|
||||||
|
|
||||||
@property
|
|
||||||
def url(self) -> str:
|
|
||||||
return self._url
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.controller"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,44 +0,0 @@
|
|||||||
from ariadne import graphql_sync
|
|
||||||
from ariadne.explorer import ExplorerPlayground
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
|
||||||
from flask import request, jsonify
|
|
||||||
|
|
||||||
from bot_api.logging.api_logger import ApiLogger
|
|
||||||
from bot_api.route.route import Route
|
|
||||||
from bot_graphql.schema import Schema
|
|
||||||
|
|
||||||
|
|
||||||
class GraphQLController:
|
|
||||||
BasePath = f"/api/graphql"
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
env: ApplicationEnvironmentABC,
|
|
||||||
logger: ApiLogger,
|
|
||||||
schema: Schema,
|
|
||||||
):
|
|
||||||
self._config = config
|
|
||||||
self._env = env
|
|
||||||
self._logger = logger
|
|
||||||
self._schema = schema
|
|
||||||
|
|
||||||
@Route.get(f"{BasePath}/playground")
|
|
||||||
@Route.authorize(skip_in_dev=True)
|
|
||||||
async def playground(self):
|
|
||||||
if self._env.environment_name != "development":
|
|
||||||
return "", 403
|
|
||||||
|
|
||||||
return ExplorerPlayground().html(None), 200
|
|
||||||
|
|
||||||
@Route.post(f"{BasePath}")
|
|
||||||
@Route.authorize(by_api_key=True)
|
|
||||||
async def graphql(self):
|
|
||||||
data = request.get_json()
|
|
||||||
|
|
||||||
# Note: Passing the request to the context is optional.
|
|
||||||
# In Flask, the current request is always accessible as flask.request
|
|
||||||
success, result = graphql_sync(self._schema.schema, data, context_value=request)
|
|
||||||
|
|
||||||
return jsonify(result), 200 if success else 400
|
|
@@ -1,84 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
|
||||||
from cpl_core.mailing import EMail, EMailClientABC, EMailClientSettings
|
|
||||||
from cpl_translation import TranslatePipe
|
|
||||||
from flask import jsonify
|
|
||||||
|
|
||||||
from bot_api.api import Api
|
|
||||||
from bot_api.configuration.authentication_settings import AuthenticationSettings
|
|
||||||
from bot_api.logging.api_logger import ApiLogger
|
|
||||||
from bot_api.model.settings_dto import SettingsDTO
|
|
||||||
from bot_api.model.version_dto import VersionDTO
|
|
||||||
from bot_api.route.route import Route
|
|
||||||
|
|
||||||
|
|
||||||
class GuiController:
|
|
||||||
BasePath = f"/api/gui"
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
env: ApplicationEnvironmentABC,
|
|
||||||
logger: ApiLogger,
|
|
||||||
t: TranslatePipe,
|
|
||||||
api: Api,
|
|
||||||
mail_settings: EMailClientSettings,
|
|
||||||
mailer: EMailClientABC,
|
|
||||||
auth_settings: AuthenticationSettings,
|
|
||||||
):
|
|
||||||
self._config = config
|
|
||||||
self._env = env
|
|
||||||
self._logger = logger
|
|
||||||
self._t = t
|
|
||||||
self._api = api
|
|
||||||
self._mail_settings = mail_settings
|
|
||||||
self._mailer = mailer
|
|
||||||
self._auth_settings = auth_settings
|
|
||||||
|
|
||||||
@Route.get(f"{BasePath}/api-version")
|
|
||||||
async def api_version(self):
|
|
||||||
import bot_api
|
|
||||||
|
|
||||||
version = bot_api.version_info
|
|
||||||
return VersionDTO(version.major, version.minor, version.micro).to_dict()
|
|
||||||
|
|
||||||
@Route.get(f"{BasePath}/settings")
|
|
||||||
@Route.authorize
|
|
||||||
async def settings(self):
|
|
||||||
import bot_api
|
|
||||||
|
|
||||||
version = bot_api.version_info
|
|
||||||
|
|
||||||
return jsonify(
|
|
||||||
SettingsDTO(
|
|
||||||
"",
|
|
||||||
VersionDTO(version.major, version.minor, version.micro),
|
|
||||||
os.path.abspath(os.path.join(self._env.working_directory, "config")),
|
|
||||||
"/",
|
|
||||||
"/",
|
|
||||||
self._auth_settings.token_expire_time,
|
|
||||||
self._auth_settings.refresh_token_expire_time,
|
|
||||||
self._mail_settings.user_name,
|
|
||||||
self._mail_settings.port,
|
|
||||||
self._mail_settings.host,
|
|
||||||
self._mail_settings.user_name,
|
|
||||||
self._mail_settings.user_name,
|
|
||||||
).to_dict()
|
|
||||||
)
|
|
||||||
|
|
||||||
@Route.post(f"{BasePath}/send-test-mail/<email>")
|
|
||||||
@Route.authorize
|
|
||||||
async def send_test_mail(self, email: str):
|
|
||||||
mail = EMail()
|
|
||||||
mail.add_header("Mime-Version: 1.0")
|
|
||||||
mail.add_header("Content-Type: text/plain; charset=utf-8")
|
|
||||||
mail.add_header("Content-Transfer-Encoding: quoted-printable")
|
|
||||||
mail.add_receiver(email)
|
|
||||||
mail.subject = self._t.transform("api.api.test_mail.subject")
|
|
||||||
mail.body = self._t.transform("api.api.test_mail.message").format(
|
|
||||||
self._env.host_name, self._env.environment_name
|
|
||||||
)
|
|
||||||
self._mailer.send_mail(mail)
|
|
||||||
return "", 200
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.event"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.exception"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.filter"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.filter.discord"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.logging"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.model"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,136 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_api.abc.dto_abc import DtoABC
|
|
||||||
from bot_api.model.user_dto import UserDTO
|
|
||||||
from bot_data.model.auth_role_enum import AuthRoleEnum
|
|
||||||
|
|
||||||
|
|
||||||
class AuthUserDTO(DtoABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: int = None,
|
|
||||||
first_name: str = None,
|
|
||||||
last_name: str = None,
|
|
||||||
email: str = None,
|
|
||||||
password: str = None,
|
|
||||||
confirmation_id: Optional[str] = None,
|
|
||||||
auth_role: AuthRoleEnum = None,
|
|
||||||
users: List[UserDTO] = None,
|
|
||||||
created_at: datetime = None,
|
|
||||||
modified_at: datetime = None,
|
|
||||||
):
|
|
||||||
DtoABC.__init__(self)
|
|
||||||
|
|
||||||
self._id = id
|
|
||||||
self._first_name = first_name
|
|
||||||
self._last_name = last_name
|
|
||||||
self._email = email
|
|
||||||
self._password = password
|
|
||||||
self._is_confirmed = confirmation_id is None
|
|
||||||
self._auth_role = auth_role
|
|
||||||
self._created_at = created_at
|
|
||||||
self._modified_at = modified_at
|
|
||||||
|
|
||||||
if users is None:
|
|
||||||
self._users = List(UserDTO)
|
|
||||||
else:
|
|
||||||
self._users = users
|
|
||||||
|
|
||||||
@property
|
|
||||||
def id(self) -> int:
|
|
||||||
return self._id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def first_name(self) -> str:
|
|
||||||
return self._first_name
|
|
||||||
|
|
||||||
@first_name.setter
|
|
||||||
def first_name(self, value: str):
|
|
||||||
self._first_name = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def last_name(self) -> str:
|
|
||||||
return self._last_name
|
|
||||||
|
|
||||||
@last_name.setter
|
|
||||||
def last_name(self, value: str):
|
|
||||||
self._last_name = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def email(self) -> str:
|
|
||||||
return self._email
|
|
||||||
|
|
||||||
@email.setter
|
|
||||||
def email(self, value: str):
|
|
||||||
self._email = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def password(self) -> str:
|
|
||||||
return self._password
|
|
||||||
|
|
||||||
@password.setter
|
|
||||||
def password(self, value: str):
|
|
||||||
self._password = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_confirmed(self) -> Optional[str]:
|
|
||||||
return self._is_confirmed
|
|
||||||
|
|
||||||
@is_confirmed.setter
|
|
||||||
def is_confirmed(self, value: Optional[str]):
|
|
||||||
self._is_confirmed = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def auth_role(self) -> AuthRoleEnum:
|
|
||||||
return self._auth_role
|
|
||||||
|
|
||||||
@auth_role.setter
|
|
||||||
def auth_role(self, value: AuthRoleEnum):
|
|
||||||
self._auth_role = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def users(self) -> List[UserDTO]:
|
|
||||||
return self._users
|
|
||||||
|
|
||||||
@property
|
|
||||||
def created_at(self) -> datetime:
|
|
||||||
return self._created_at
|
|
||||||
|
|
||||||
@property
|
|
||||||
def modified_at(self) -> datetime:
|
|
||||||
return self._modified_at
|
|
||||||
|
|
||||||
def from_dict(self, values: dict):
|
|
||||||
self._id = values["id"]
|
|
||||||
self._first_name = values["firstName"]
|
|
||||||
self._last_name = values["lastName"]
|
|
||||||
self._email = values["email"]
|
|
||||||
self._password = values["password"]
|
|
||||||
self._is_confirmed = values["isConfirmed"]
|
|
||||||
self._auth_role = AuthRoleEnum(values["authRole"])
|
|
||||||
if "users" in values:
|
|
||||||
self._users = List(UserDTO)
|
|
||||||
for u in values["users"]:
|
|
||||||
user = UserDTO()
|
|
||||||
user.from_dict(u)
|
|
||||||
self._users.add(user)
|
|
||||||
|
|
||||||
self._created_at = values["createdAt"]
|
|
||||||
self._modified_at = values["modifiedAt"]
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
return {
|
|
||||||
"id": self._id,
|
|
||||||
"firstName": self._first_name,
|
|
||||||
"lastName": self._last_name,
|
|
||||||
"email": self._email,
|
|
||||||
"password": self._password,
|
|
||||||
"isConfirmed": self._is_confirmed,
|
|
||||||
"authRole": self._auth_role.value,
|
|
||||||
"users": self._users.select(lambda u: u.to_dict()).to_list(),
|
|
||||||
"createdAt": self._created_at,
|
|
||||||
"modifiedAt": self._modified_at,
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.model.discord"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,66 +0,0 @@
|
|||||||
from bot_api.abc.dto_abc import DtoABC
|
|
||||||
from bot_api.model.version_dto import VersionDTO
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsDTO(DtoABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
web_version: str,
|
|
||||||
api_version: VersionDTO,
|
|
||||||
config_path: str,
|
|
||||||
web_base_url: str,
|
|
||||||
api_base_url: str,
|
|
||||||
token_expire_time: int,
|
|
||||||
refresh_token_expire_time: int,
|
|
||||||
mail_user: str,
|
|
||||||
mail_port: int,
|
|
||||||
mail_host: str,
|
|
||||||
mail_transceiver: str,
|
|
||||||
mail_transceiver_address: str,
|
|
||||||
):
|
|
||||||
DtoABC.__init__(self)
|
|
||||||
|
|
||||||
self._web_version = web_version
|
|
||||||
self._api_version = api_version
|
|
||||||
self._config_path = config_path
|
|
||||||
self._web_base_url = web_base_url
|
|
||||||
self._api_base_url = api_base_url
|
|
||||||
|
|
||||||
self._token_expire_time = token_expire_time
|
|
||||||
self._refresh_token_expire_time = refresh_token_expire_time
|
|
||||||
|
|
||||||
self._mail_user = mail_user
|
|
||||||
self._mail_port = mail_port
|
|
||||||
self._mail_host = mail_host
|
|
||||||
self._mail_transceiver = mail_transceiver
|
|
||||||
self._mail_transceiver_address = mail_transceiver_address
|
|
||||||
|
|
||||||
def from_dict(self, values: dict):
|
|
||||||
self._web_version = values["webVersion"]
|
|
||||||
self._api_version.from_dict(values["apiVersion"])
|
|
||||||
self._config_path = values["configPath"]
|
|
||||||
self._web_base_url = values["webBaseURL"]
|
|
||||||
self._api_base_url = values["apiBaseURL"]
|
|
||||||
self._token_expire_time = values["tokenExpireTime"]
|
|
||||||
self._refresh_token_expire_time = values["refreshTokenExpireTime"]
|
|
||||||
self._mail_user = values["mailUser"]
|
|
||||||
self._mail_port = values["mailPort"]
|
|
||||||
self._mail_host = values["mailHost"]
|
|
||||||
self._mail_transceiver = values["mailTransceiver"]
|
|
||||||
self._mail_transceiver_address = values["mailTransceiverAddress"]
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
return {
|
|
||||||
"webVersion": self._web_version,
|
|
||||||
"apiVersion": self._api_version.str,
|
|
||||||
"configPath": self._config_path,
|
|
||||||
"webBaseURL": self._web_base_url,
|
|
||||||
"apiBaseURL": self._api_base_url,
|
|
||||||
"tokenExpireTime": self._token_expire_time,
|
|
||||||
"refreshTokenExpireTime": self._refresh_token_expire_time,
|
|
||||||
"mailUser": self._mail_user,
|
|
||||||
"mailPort": self._mail_port,
|
|
||||||
"mailHost": self._mail_host,
|
|
||||||
"mailTransceiver": self._mail_transceiver,
|
|
||||||
"mailTransceiverAddress": self._mail_transceiver_address,
|
|
||||||
}
|
|
@@ -1,34 +0,0 @@
|
|||||||
from bot_api.abc.dto_abc import DtoABC
|
|
||||||
|
|
||||||
|
|
||||||
class TokenDTO(DtoABC):
|
|
||||||
def __init__(self, token: str, refresh_token: str, first_login: bool = False):
|
|
||||||
DtoABC.__init__(self)
|
|
||||||
|
|
||||||
self._token = token
|
|
||||||
self._refresh_token = refresh_token
|
|
||||||
self._first_login = first_login
|
|
||||||
|
|
||||||
@property
|
|
||||||
def token(self) -> str:
|
|
||||||
return self._token
|
|
||||||
|
|
||||||
@property
|
|
||||||
def refresh_token(self) -> str:
|
|
||||||
return self._refresh_token
|
|
||||||
|
|
||||||
@property
|
|
||||||
def first_login(self) -> bool:
|
|
||||||
return self._first_login
|
|
||||||
|
|
||||||
def from_dict(self, values: dict):
|
|
||||||
self._token = values["token"]
|
|
||||||
self._refresh_token = values["refreshToken"]
|
|
||||||
self._first_login = values["firstLogin"]
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
return {
|
|
||||||
"token": self._token,
|
|
||||||
"refreshToken": self._refresh_token,
|
|
||||||
"firstLogin": self._first_login,
|
|
||||||
}
|
|
@@ -1,76 +0,0 @@
|
|||||||
from typing import Optional
|
|
||||||
|
|
||||||
from bot_api.abc.dto_abc import DtoABC
|
|
||||||
from bot_data.model.server import Server
|
|
||||||
|
|
||||||
|
|
||||||
class UserDTO(DtoABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: int = None,
|
|
||||||
dc_id: int = None,
|
|
||||||
xp: int = None,
|
|
||||||
server: Optional[Server] = None,
|
|
||||||
is_technician: Optional[bool] = None,
|
|
||||||
is_admin: Optional[bool] = None,
|
|
||||||
is_moderator: Optional[bool] = None,
|
|
||||||
):
|
|
||||||
DtoABC.__init__(self)
|
|
||||||
|
|
||||||
self._user_id = id
|
|
||||||
self._discord_id = dc_id
|
|
||||||
self._xp = xp
|
|
||||||
self._server = server
|
|
||||||
|
|
||||||
self._is_technician = is_technician
|
|
||||||
self._is_admin = is_admin
|
|
||||||
self._is_moderator = is_moderator
|
|
||||||
|
|
||||||
@property
|
|
||||||
def user_id(self) -> int:
|
|
||||||
return self._user_id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def discord_id(self) -> int:
|
|
||||||
return self._discord_id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def xp(self) -> int:
|
|
||||||
return self._xp
|
|
||||||
|
|
||||||
@xp.setter
|
|
||||||
def xp(self, value: int):
|
|
||||||
self._xp = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def server(self) -> Optional[Server]:
|
|
||||||
return self._server
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_technician(self) -> bool:
|
|
||||||
return self._is_technician if self._is_technician is not None else False
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_admin(self) -> bool:
|
|
||||||
return self._is_admin if self._is_admin is not None else False
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_moderator(self) -> bool:
|
|
||||||
return self._is_moderator if self._is_moderator is not None else False
|
|
||||||
|
|
||||||
def from_dict(self, values: dict):
|
|
||||||
self._user_id = values["id"]
|
|
||||||
self._discord_id = values["dcId"]
|
|
||||||
self._xp = values["xp"]
|
|
||||||
self._server = values["server"]
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
return {
|
|
||||||
"id": self._user_id,
|
|
||||||
"dcId": self._discord_id,
|
|
||||||
"xp": self._xp,
|
|
||||||
"server": self._server.id,
|
|
||||||
"isTechnician": self.is_technician,
|
|
||||||
"isAdmin": self.is_admin,
|
|
||||||
"isModerator": self.is_moderator,
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.route"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,171 +0,0 @@
|
|||||||
import functools
|
|
||||||
from functools import wraps
|
|
||||||
from typing import Optional, Callable, Union
|
|
||||||
|
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
|
||||||
from flask import request, jsonify
|
|
||||||
from flask_cors import cross_origin
|
|
||||||
|
|
||||||
from bot_api.abc.auth_service_abc import AuthServiceABC
|
|
||||||
from bot_api.exception.service_error_code_enum import ServiceErrorCode
|
|
||||||
from bot_api.exception.service_exception import ServiceException
|
|
||||||
from bot_api.model.error_dto import ErrorDTO
|
|
||||||
from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC
|
|
||||||
from bot_data.model.auth_role_enum import AuthRoleEnum
|
|
||||||
from bot_data.model.auth_user import AuthUser
|
|
||||||
|
|
||||||
|
|
||||||
class Route:
|
|
||||||
registered_routes = {}
|
|
||||||
|
|
||||||
_auth_users: Optional[AuthUserRepositoryABC] = None
|
|
||||||
_auth: Optional[AuthServiceABC] = None
|
|
||||||
_env = "production"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
@ServiceProviderABC.inject
|
|
||||||
def init_authorize(
|
|
||||||
cls,
|
|
||||||
env: ApplicationEnvironmentABC,
|
|
||||||
auth_users: AuthUserRepositoryABC,
|
|
||||||
auth: AuthServiceABC,
|
|
||||||
):
|
|
||||||
cls._auth_users = auth_users
|
|
||||||
cls._auth = auth
|
|
||||||
cls._env = env.environment_name
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_user(cls) -> Optional[Union[str, AuthUser]]:
|
|
||||||
token = None
|
|
||||||
api_key = None
|
|
||||||
authorization = request.headers.get("Authorization").split()
|
|
||||||
match authorization[0]:
|
|
||||||
case "Bearer":
|
|
||||||
token = authorization[1]
|
|
||||||
case "API-Key":
|
|
||||||
api_key = authorization[1]
|
|
||||||
|
|
||||||
if api_key is not None:
|
|
||||||
return "system"
|
|
||||||
|
|
||||||
if token is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
jwt = cls._auth.decode_token(token)
|
|
||||||
user = cls._auth_users.get_auth_user_by_email(jwt["email"])
|
|
||||||
return user
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def authorize(
|
|
||||||
cls,
|
|
||||||
f: Callable = None,
|
|
||||||
role: AuthRoleEnum = None,
|
|
||||||
skip_in_dev=False,
|
|
||||||
by_api_key=False,
|
|
||||||
):
|
|
||||||
if f is None:
|
|
||||||
return functools.partial(cls.authorize, role=role, skip_in_dev=skip_in_dev, by_api_key=by_api_key)
|
|
||||||
|
|
||||||
@wraps(f)
|
|
||||||
async def decorator(*args, **kwargs):
|
|
||||||
if skip_in_dev and cls._env == "development":
|
|
||||||
return await f(*args, **kwargs)
|
|
||||||
|
|
||||||
token = None
|
|
||||||
api_key = None
|
|
||||||
if "Authorization" in request.headers:
|
|
||||||
if " " not in request.headers.get("Authorization"):
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token not set")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 401
|
|
||||||
|
|
||||||
authorization = request.headers.get("Authorization").split()
|
|
||||||
match authorization[0]:
|
|
||||||
case "Bearer":
|
|
||||||
token = authorization[1]
|
|
||||||
case "API-Key":
|
|
||||||
api_key = authorization[1]
|
|
||||||
|
|
||||||
if api_key is not None:
|
|
||||||
valid = False
|
|
||||||
try:
|
|
||||||
valid = cls._auth.verify_api_key(api_key)
|
|
||||||
except ServiceException as e:
|
|
||||||
error = ErrorDTO(e.error_code, e.message)
|
|
||||||
return jsonify(error.to_dict()), 403
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify(e), 500
|
|
||||||
|
|
||||||
if not valid:
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"API-Key invalid")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 401
|
|
||||||
|
|
||||||
return await f(*args, **kwargs)
|
|
||||||
|
|
||||||
if token is None:
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token not set")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 401
|
|
||||||
|
|
||||||
if cls._auth_users is None or cls._auth is None:
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Authorize is not initialized")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 401
|
|
||||||
|
|
||||||
if not cls._auth.verify_login(token):
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token expired")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 401
|
|
||||||
|
|
||||||
token = cls._auth.decode_token(token)
|
|
||||||
if token is None or "email" not in token:
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token invalid")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 401
|
|
||||||
|
|
||||||
user = cls._auth_users.get_auth_user_by_email(token["email"])
|
|
||||||
if user is None:
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Token invalid")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 401
|
|
||||||
|
|
||||||
if role is not None and user.auth_role.value < role.value:
|
|
||||||
ex = ServiceException(ServiceErrorCode.Unauthorized, f"Role {role} required")
|
|
||||||
error = ErrorDTO(ex.error_code, ex.message)
|
|
||||||
return jsonify(error.to_dict()), 403
|
|
||||||
|
|
||||||
return await f(*args, **kwargs)
|
|
||||||
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def route(cls, path=None, **kwargs):
|
|
||||||
# simple decorator for class based views
|
|
||||||
def inner(fn):
|
|
||||||
cross_origin(fn)
|
|
||||||
cls.registered_routes[path] = (fn, kwargs)
|
|
||||||
return fn
|
|
||||||
|
|
||||||
return inner
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get(cls, path=None, **kwargs):
|
|
||||||
return cls.route(path, methods=["GET"], **kwargs)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def post(cls, path=None, **kwargs):
|
|
||||||
return cls.route(path, methods=["POST"], **kwargs)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def head(cls, path=None, **kwargs):
|
|
||||||
return cls.route(path, methods=["HEAD"], **kwargs)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def put(cls, path=None, **kwargs):
|
|
||||||
return cls.route(path, methods=["PUT"], **kwargs)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def delete(cls, path=None, **kwargs):
|
|
||||||
return cls.route(path, methods=["DELETE"], **kwargs)
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.service"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_api.transformer"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,81 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_api.abc.transformer_abc import TransformerABC
|
|
||||||
from bot_api.model.auth_user_dto import AuthUserDTO
|
|
||||||
from bot_api.model.user_dto import UserDTO
|
|
||||||
from bot_data.model.auth_role_enum import AuthRoleEnum
|
|
||||||
from bot_data.model.auth_user import AuthUser
|
|
||||||
from bot_data.model.user import User
|
|
||||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
|
|
||||||
|
|
||||||
class AuthUserTransformer(TransformerABC):
|
|
||||||
@staticmethod
|
|
||||||
def to_db(dto: AuthUserDTO) -> AuthUser:
|
|
||||||
return AuthUser(
|
|
||||||
dto.first_name,
|
|
||||||
dto.last_name,
|
|
||||||
dto.email,
|
|
||||||
dto.password,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
datetime.now(),
|
|
||||||
AuthRoleEnum.normal if dto.auth_role is None else AuthRoleEnum(dto.auth_role),
|
|
||||||
auth_user_id=0 if dto.id is None else dto.id,
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@ServiceProviderABC.inject
|
|
||||||
def _is_technician(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC):
|
|
||||||
guild = bot.get_guild(user.server.discord_id)
|
|
||||||
member = guild.get_member(user.discord_id)
|
|
||||||
return permissions.is_member_technician(member)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@ServiceProviderABC.inject
|
|
||||||
def _is_admin(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC):
|
|
||||||
guild = bot.get_guild(user.server.discord_id)
|
|
||||||
member = guild.get_member(user.discord_id)
|
|
||||||
return permissions.is_member_admin(member)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@ServiceProviderABC.inject
|
|
||||||
def _is_moderator(user: User, bot: DiscordBotServiceABC, permissions: PermissionServiceABC):
|
|
||||||
guild = bot.get_guild(user.server.discord_id)
|
|
||||||
member = guild.get_member(user.discord_id)
|
|
||||||
return permissions.is_member_moderator(member)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def to_dto(cls, db: AuthUser, password: str = None) -> AuthUserDTO:
|
|
||||||
return AuthUserDTO(
|
|
||||||
db.id,
|
|
||||||
db.first_name,
|
|
||||||
db.last_name,
|
|
||||||
db.email,
|
|
||||||
"" if password is None else password,
|
|
||||||
db.confirmation_id,
|
|
||||||
db.auth_role,
|
|
||||||
List(
|
|
||||||
UserDTO,
|
|
||||||
db.users.select(
|
|
||||||
lambda u: UserDTO(
|
|
||||||
u.id,
|
|
||||||
u.discord_id,
|
|
||||||
u.xp,
|
|
||||||
u.server,
|
|
||||||
cls._is_technician(u),
|
|
||||||
cls._is_admin(u),
|
|
||||||
cls._is_moderator(u),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
db.created_at,
|
|
||||||
db.modified_at,
|
|
||||||
)
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.abc"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,81 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Callable, Union
|
|
||||||
|
|
||||||
import discord
|
|
||||||
from cpl_query.extension import List
|
|
||||||
from discord.ext.commands import Context
|
|
||||||
|
|
||||||
from bot_data.model.auto_role_rule import AutoRoleRule
|
|
||||||
from bot_data.model.server_config import ServerConfig
|
|
||||||
from bot_data.model.user import User
|
|
||||||
|
|
||||||
|
|
||||||
class ClientUtilsABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def received_command(self, guild_id: int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def moved_user(self, guild_id: int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def moved_users(self, guild_id: int, count: int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_client(self, dc_ic: int, guild_id: int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def check_if_bot_is_ready_yet(self) -> bool:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def check_if_bot_is_ready_yet_and_respond(self, ctx: Context) -> bool:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def presence_game(self, t_key: str):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour(
|
|
||||||
self,
|
|
||||||
created_at: datetime,
|
|
||||||
user: User,
|
|
||||||
settings: ServerConfig,
|
|
||||||
is_reaction: bool = False,
|
|
||||||
) -> bool:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_ontime_for_user(self, user: User) -> float:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def react_to_message_by_auto_role_rule(
|
|
||||||
self,
|
|
||||||
discord_channel_id: int,
|
|
||||||
discord_message_id: int,
|
|
||||||
rule: AutoRoleRule,
|
|
||||||
guild: discord.Guild,
|
|
||||||
):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def set_maintenance_mode(self, state: bool):
|
|
||||||
pass
|
|
@@ -1,67 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from typing import Union, Optional
|
|
||||||
|
|
||||||
import discord
|
|
||||||
from cpl_query.extension import List
|
|
||||||
from discord import Interaction
|
|
||||||
from discord.ext.commands import Context
|
|
||||||
|
|
||||||
|
|
||||||
class MessageServiceABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def delete_message(self, message: discord.Message, without_tracking=False):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def send_channel_message(
|
|
||||||
self,
|
|
||||||
channel: discord.TextChannel,
|
|
||||||
message: Union[str, discord.Embed],
|
|
||||||
is_persistent: bool = False,
|
|
||||||
wait_before_delete: int = None,
|
|
||||||
without_tracking=False,
|
|
||||||
):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def send_dm_message(
|
|
||||||
self,
|
|
||||||
message: Union[str, discord.Embed],
|
|
||||||
receiver: Union[discord.User, discord.Member],
|
|
||||||
without_tracking=False,
|
|
||||||
):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def send_ctx_msg(
|
|
||||||
self,
|
|
||||||
ctx: Context,
|
|
||||||
message: Union[str, discord.Embed],
|
|
||||||
file: discord.File = None,
|
|
||||||
is_persistent: bool = False,
|
|
||||||
is_public: bool = False,
|
|
||||||
wait_before_delete: int = None,
|
|
||||||
without_tracking=True,
|
|
||||||
) -> Optional[discord.Message]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def send_interaction_msg(
|
|
||||||
self,
|
|
||||||
interaction: Interaction,
|
|
||||||
message: Union[str, discord.Embed],
|
|
||||||
is_persistent: bool = False,
|
|
||||||
is_public: bool = False,
|
|
||||||
wait_before_delete: int = None,
|
|
||||||
without_tracking=True,
|
|
||||||
**kwargs
|
|
||||||
):
|
|
||||||
pass
|
|
@@ -1,33 +0,0 @@
|
|||||||
import asyncio
|
|
||||||
from abc import abstractmethod
|
|
||||||
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
from bot_core.environment_variables import MAINTENANCE
|
|
||||||
from bot_core.logging.task_logger import TaskLogger
|
|
||||||
|
|
||||||
|
|
||||||
class TaskABC(commands.Cog):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
commands.Cog.__init__(self)
|
|
||||||
|
|
||||||
@ServiceProviderABC.inject
|
|
||||||
def _is_maintenance(self, config: ConfigurationABC) -> bool:
|
|
||||||
return config.get_configuration(MAINTENANCE) is True
|
|
||||||
|
|
||||||
@ServiceProviderABC.inject
|
|
||||||
async def _wait_until_ready(self, config: ConfigurationABC, logger: TaskLogger, bot: DiscordBotServiceABC):
|
|
||||||
logger.debug(__name__, f"Waiting before {type(self).__name__}")
|
|
||||||
await bot.wait_until_ready()
|
|
||||||
|
|
||||||
async def wait():
|
|
||||||
is_ready = config.get_configuration("IS_READY") is True
|
|
||||||
if not is_ready:
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
await wait()
|
|
||||||
|
|
||||||
await wait()
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.configuration"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,25 +0,0 @@
|
|||||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
|
||||||
from cpl_core.utils.json_processor import JSONProcessor
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_core.configuration.file_logging_settings import FileLoggingSettings
|
|
||||||
|
|
||||||
|
|
||||||
class BotLoggingSettings(ConfigurationModelABC):
|
|
||||||
def __init__(self, **kwargs: dict):
|
|
||||||
ConfigurationModelABC.__init__(self)
|
|
||||||
self._files: List[FileLoggingSettings] = List(FileLoggingSettings)
|
|
||||||
|
|
||||||
if kwargs is not None:
|
|
||||||
self._files_from_dict(kwargs)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def files(self) -> List[FileLoggingSettings]:
|
|
||||||
return self._files
|
|
||||||
|
|
||||||
def _files_from_dict(self, settings: dict):
|
|
||||||
files = List(FileLoggingSettings)
|
|
||||||
for s in settings:
|
|
||||||
settings[s]["Key"] = s
|
|
||||||
files.append(JSONProcessor.process(FileLoggingSettings, settings[s]))
|
|
||||||
self._files = files
|
|
@@ -1,29 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class FeatureFlagsEnum(Enum):
|
|
||||||
# modules
|
|
||||||
achievements_module = "AchievementsModule"
|
|
||||||
api_module = "ApiModule"
|
|
||||||
auto_role_module = "AutoRoleModule"
|
|
||||||
base_module = "BaseModule"
|
|
||||||
boot_log_module = "BootLogModule"
|
|
||||||
core_module = "CoreModule"
|
|
||||||
core_extension_module = "CoreExtensionModule"
|
|
||||||
config_module = "ConfigModule"
|
|
||||||
data_module = "DataModule"
|
|
||||||
database_module = "DatabaseModule"
|
|
||||||
level_module = "LevelModule"
|
|
||||||
moderator_module = "ModeratorModule"
|
|
||||||
permission_module = "PermissionModule"
|
|
||||||
short_role_name_module = "ShortRoleNameModule"
|
|
||||||
steam_special_offers_module = "SteamSpecialOffersModule"
|
|
||||||
# features
|
|
||||||
api_only = "ApiOnly"
|
|
||||||
presence = "Presence"
|
|
||||||
version_in_presence = "VersionInPresence"
|
|
||||||
game_server = "GameServer"
|
|
||||||
sync_xp = "SyncXp"
|
|
||||||
short_role_name = "ShortRoleName"
|
|
||||||
technician_full_access = "TechnicianFullAccess"
|
|
||||||
steam_special_offers = "SteamSpecialOffers"
|
|
@@ -1,63 +0,0 @@
|
|||||||
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
|
|
||||||
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
|
|
||||||
|
|
||||||
class FeatureFlagsSettings(ConfigurationModelABC):
|
|
||||||
_flags = {
|
|
||||||
# modules
|
|
||||||
FeatureFlagsEnum.achievements_module.value: False, # 14.06.2023 #268
|
|
||||||
FeatureFlagsEnum.api_module.value: False, # 13.10.2022 #70
|
|
||||||
FeatureFlagsEnum.auto_role_module.value: False, # 03.10.2022 #54
|
|
||||||
FeatureFlagsEnum.base_module.value: True, # 02.10.2022 #48
|
|
||||||
FeatureFlagsEnum.boot_log_module.value: True, # 02.10.2022 #48
|
|
||||||
FeatureFlagsEnum.core_module.value: True, # 03.10.2022 #56
|
|
||||||
FeatureFlagsEnum.core_extension_module.value: True, # 03.10.2022 #56
|
|
||||||
FeatureFlagsEnum.data_module.value: True, # 03.10.2022 #56
|
|
||||||
FeatureFlagsEnum.database_module.value: True, # 02.10.2022 #48
|
|
||||||
FeatureFlagsEnum.moderator_module.value: False, # 02.10.2022 #48
|
|
||||||
FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48
|
|
||||||
FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127
|
|
||||||
FeatureFlagsEnum.short_role_name_module.value: True, # 28.09.2023 #378
|
|
||||||
FeatureFlagsEnum.steam_special_offers_module.value: True, # 11.10.2023 #188
|
|
||||||
# features
|
|
||||||
FeatureFlagsEnum.api_only.value: False, # 13.10.2022 #70
|
|
||||||
FeatureFlagsEnum.presence.value: True, # 03.10.2022 #56
|
|
||||||
FeatureFlagsEnum.version_in_presence.value: False, # 21.03.2023 #253
|
|
||||||
FeatureFlagsEnum.game_server.value: False, # 25.09.2023 #366
|
|
||||||
FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366
|
|
||||||
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
|
|
||||||
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
|
|
||||||
FeatureFlagsEnum.steam_special_offers.value: False, # 11.10.2023 #188
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, **kwargs: dict):
|
|
||||||
ConfigurationModelABC.__init__(self)
|
|
||||||
|
|
||||||
if len(kwargs.keys()) == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
for flag in [f.value for f in FeatureFlagsEnum]:
|
|
||||||
self._load_flag(kwargs, FeatureFlagsEnum(flag))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_flag_from_dict(cls, flags: dict, key: FeatureFlagsEnum) -> bool:
|
|
||||||
def get_flag():
|
|
||||||
if key.value not in cls._flags:
|
|
||||||
return False
|
|
||||||
return cls._flags[key.value]
|
|
||||||
|
|
||||||
if key.value not in flags:
|
|
||||||
return get_flag()
|
|
||||||
return flags[key.value]
|
|
||||||
|
|
||||||
def get_flag(self, key: FeatureFlagsEnum) -> bool:
|
|
||||||
if key.value not in self._flags:
|
|
||||||
return False
|
|
||||||
return self._flags[key.value]
|
|
||||||
|
|
||||||
def _load_flag(self, settings: dict, key: FeatureFlagsEnum):
|
|
||||||
if key.value not in settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._flags[key.value] = bool(settings[key.value])
|
|
@@ -1,19 +0,0 @@
|
|||||||
from cpl_core.logging import LoggingSettings, LoggingLevelEnum
|
|
||||||
|
|
||||||
|
|
||||||
class FileLoggingSettings(LoggingSettings):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
key: str,
|
|
||||||
path: str = None,
|
|
||||||
filename: str = None,
|
|
||||||
console_log_level: LoggingLevelEnum = None,
|
|
||||||
file_log_level: LoggingLevelEnum = None,
|
|
||||||
):
|
|
||||||
LoggingSettings.__init__(self, path, filename, console_log_level, file_log_level)
|
|
||||||
|
|
||||||
self._key = key
|
|
||||||
|
|
||||||
@property
|
|
||||||
def key(self) -> str:
|
|
||||||
return self._key
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.core_extension"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,35 +0,0 @@
|
|||||||
import asyncio
|
|
||||||
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.logging import LoggerABC
|
|
||||||
from cpl_discord.events import OnReadyABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from cpl_translation import TranslatePipe
|
|
||||||
|
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
|
||||||
from bot_core.environment_variables import MAINTENANCE
|
|
||||||
|
|
||||||
|
|
||||||
class CoreExtensionOnReadyEvent(OnReadyABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
logger: LoggerABC,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
client_utils: ClientUtilsABC,
|
|
||||||
t: TranslatePipe,
|
|
||||||
):
|
|
||||||
OnReadyABC.__init__(self)
|
|
||||||
|
|
||||||
self._config = config
|
|
||||||
self._logger = logger
|
|
||||||
self._bot = bot
|
|
||||||
self._client_utils = client_utils
|
|
||||||
self._t = t
|
|
||||||
|
|
||||||
self._logger.info(__name__, f"Module {type(self)} loaded")
|
|
||||||
|
|
||||||
async def on_ready(self):
|
|
||||||
self._logger.debug(__name__, f"Module {type(self)} started")
|
|
||||||
await self._client_utils.set_maintenance_mode(self._config.get_configuration(MAINTENANCE))
|
|
||||||
self._logger.trace(__name__, f"Module {type(self)} stopped")
|
|
@@ -1,2 +0,0 @@
|
|||||||
MIGRATION_ONLY = "MIGRATION_ONLY"
|
|
||||||
MAINTENANCE = "MAINTENANCE"
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.events"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,29 +0,0 @@
|
|||||||
from cpl_core.logging import LoggerABC
|
|
||||||
from cpl_discord.events import OnReadyABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from cpl_translation import TranslatePipe
|
|
||||||
|
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
|
||||||
|
|
||||||
|
|
||||||
class CoreOnReadyEvent(OnReadyABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
logger: LoggerABC,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
client_utils: ClientUtilsABC,
|
|
||||||
t: TranslatePipe,
|
|
||||||
):
|
|
||||||
OnReadyABC.__init__(self)
|
|
||||||
|
|
||||||
self._logger = logger
|
|
||||||
self._bot = bot
|
|
||||||
self._client_utils = client_utils
|
|
||||||
self._t = t
|
|
||||||
|
|
||||||
self._logger.info(__name__, f"Module {type(self)} loaded")
|
|
||||||
|
|
||||||
async def on_ready(self):
|
|
||||||
self._logger.debug(__name__, f"Module {type(self)} started")
|
|
||||||
await self._client_utils.presence_game("common.presence.booting")
|
|
||||||
self._logger.trace(__name__, f"Module {type(self)} stopped")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.exception"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.helper"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,35 +0,0 @@
|
|||||||
import inspect
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
|
||||||
from bot_core.exception.check_error import CheckError
|
|
||||||
|
|
||||||
|
|
||||||
class EventChecks:
|
|
||||||
_client_utils: Optional[ClientUtilsABC] = None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def init(
|
|
||||||
cls,
|
|
||||||
client_utils: ClientUtilsABC,
|
|
||||||
):
|
|
||||||
cls._client_utils = client_utils
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def check_is_ready(cls, func):
|
|
||||||
async def check_if_bot_is_ready(*args, **kwargs):
|
|
||||||
result = await cls._client_utils.check_if_bot_is_ready_yet()
|
|
||||||
if not result:
|
|
||||||
|
|
||||||
def empty(*args, **kwargs):
|
|
||||||
return
|
|
||||||
|
|
||||||
return empty
|
|
||||||
return await func(*args, **kwargs)
|
|
||||||
|
|
||||||
check_if_bot_is_ready.__name__ = func.__name__
|
|
||||||
sig = inspect.signature(func)
|
|
||||||
check_if_bot_is_ready.__signature__ = sig.replace(parameters=tuple(sig.parameters.values())[1:])
|
|
||||||
return check_if_bot_is_ready
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.logging"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,15 +0,0 @@
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
|
||||||
from cpl_core.time import TimeFormatSettings
|
|
||||||
|
|
||||||
from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC
|
|
||||||
|
|
||||||
|
|
||||||
class TaskLogger(CustomFileLoggerABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
time_format: TimeFormatSettings,
|
|
||||||
env: ApplicationEnvironmentABC,
|
|
||||||
):
|
|
||||||
CustomFileLoggerABC.__init__(self, "Task", config, time_format, env)
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.pipes"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_core.service"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,256 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
from typing import Callable, Union
|
|
||||||
|
|
||||||
import discord
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
|
||||||
from cpl_core.logging import LoggerABC
|
|
||||||
from cpl_core.time import TimeFormatSettings
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
from cpl_translation import TranslatePipe
|
|
||||||
from discord import Guild
|
|
||||||
from discord.ext.commands import Context
|
|
||||||
|
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
|
||||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|
||||||
from bot_core.environment_variables import MAINTENANCE
|
|
||||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
|
||||||
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.model.auto_role_rule import AutoRoleRule
|
|
||||||
from bot_data.model.server_config import ServerConfig
|
|
||||||
from bot_data.model.user import User
|
|
||||||
from bot_data.model.user_message_count_per_hour import UserMessageCountPerHour
|
|
||||||
|
|
||||||
|
|
||||||
class ClientUtilsService(ClientUtilsABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
logger: LoggerABC,
|
|
||||||
time_format: TimeFormatSettings,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
servers: ServerRepositoryABC,
|
|
||||||
clients: ClientRepositoryABC,
|
|
||||||
user_joined_vc: UserJoinedVoiceChannelRepositoryABC,
|
|
||||||
umcphs: UserMessageCountPerHourRepositoryABC,
|
|
||||||
message_service: MessageServiceABC,
|
|
||||||
db: DatabaseContextABC,
|
|
||||||
t: TranslatePipe,
|
|
||||||
feature_flags: FeatureFlagsSettings,
|
|
||||||
):
|
|
||||||
ClientUtilsABC.__init__(self)
|
|
||||||
self._config = config
|
|
||||||
self._logger = logger
|
|
||||||
self._time_format = time_format
|
|
||||||
self._bot = bot
|
|
||||||
self._servers = servers
|
|
||||||
self._umcphs = umcphs
|
|
||||||
self._clients = clients
|
|
||||||
self._user_joined_voice_channel = user_joined_vc
|
|
||||||
self._message_service = message_service
|
|
||||||
self._db = db
|
|
||||||
self._t = t
|
|
||||||
self._feature_flags = feature_flags
|
|
||||||
|
|
||||||
def received_command(self, guild_id: int):
|
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
|
||||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
|
||||||
client.received_command_count += 1
|
|
||||||
self._clients.update_client(client)
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
def moved_user(self, guild_id: int):
|
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
|
||||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
|
||||||
client.moved_users_count += 1
|
|
||||||
self._clients.update_client(client)
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
def moved_users(self, guild_id: int, count: int):
|
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
|
||||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
|
||||||
client.moved_users_count += count
|
|
||||||
self._clients.update_client(client)
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
def get_client(self, dc_ic: int, guild_id: int):
|
|
||||||
server = self._servers.get_server_by_discord_id(guild_id)
|
|
||||||
client = self._clients.find_client_by_discord_id_and_server_id(self._bot.user.id, server.id)
|
|
||||||
return client
|
|
||||||
|
|
||||||
async def check_if_bot_is_ready_yet(self) -> bool:
|
|
||||||
if self._config.get_configuration(MAINTENANCE):
|
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"Bot is in maintenance mode",
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
if self._config.get_configuration("IS_READY") is True:
|
|
||||||
return True
|
|
||||||
|
|
||||||
self._logger.debug(
|
|
||||||
__name__,
|
|
||||||
f'Bot is not ready yet {self._t.transform("common.errors.bot_not_ready_yet")}',
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def check_if_bot_is_ready_yet_and_respond(self, ctx: Context) -> bool:
|
|
||||||
result = await self.check_if_bot_is_ready_yet()
|
|
||||||
if not result:
|
|
||||||
await self._message_service.send_ctx_msg(
|
|
||||||
ctx,
|
|
||||||
self._t.transform("common.errors.bot_not_ready_yet"),
|
|
||||||
without_tracking=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
async def presence_game(self, t_key: str):
|
|
||||||
if not self._feature_flags.get_flag(FeatureFlagsEnum.presence):
|
|
||||||
return
|
|
||||||
|
|
||||||
import bot
|
|
||||||
|
|
||||||
if self._feature_flags.get_flag(FeatureFlagsEnum.version_in_presence):
|
|
||||||
name = f"{bot.__version__} {self._t.transform(t_key)}"
|
|
||||||
else:
|
|
||||||
name = self._t.transform(t_key)
|
|
||||||
|
|
||||||
await self._bot.change_presence(activity=discord.Game(name=name))
|
|
||||||
self._logger.info(__name__, f"Set presence {name}")
|
|
||||||
|
|
||||||
def get_auto_complete_list(self, _l: List, current: str, select: Callable = None) -> List:
|
|
||||||
if current != "":
|
|
||||||
if select is None:
|
|
||||||
select = lambda x: x
|
|
||||||
|
|
||||||
sl = _l.select(select)
|
|
||||||
sl = sl.where(lambda x: current in x)
|
|
||||||
if current in sl:
|
|
||||||
sl = sl.skip(sl.index_of(current))
|
|
||||||
|
|
||||||
_l = _l.where(lambda x: select(x) in sl)
|
|
||||||
|
|
||||||
return _l.take(25)
|
|
||||||
|
|
||||||
def is_message_xp_count_by_hour_higher_that_max_message_count_per_hour(
|
|
||||||
self,
|
|
||||||
created_at: datetime,
|
|
||||||
user: User,
|
|
||||||
settings: ServerConfig,
|
|
||||||
is_reaction: bool = False,
|
|
||||||
) -> bool:
|
|
||||||
umcph = None
|
|
||||||
try:
|
|
||||||
umcph = self._umcphs.find_user_message_count_per_hour_by_user_id_and_date(user.id, created_at)
|
|
||||||
if umcph is None:
|
|
||||||
self._umcphs.add_user_message_count_per_hour(
|
|
||||||
UserMessageCountPerHour(
|
|
||||||
created_at.strftime(self._time_format.date_time_format),
|
|
||||||
created_at.hour,
|
|
||||||
0,
|
|
||||||
user,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
umcph = self._umcphs.get_user_message_count_per_hour_by_user_id_and_date(user.id, created_at)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(
|
|
||||||
__name__,
|
|
||||||
f"Cannot add user message count per hour with id {umcph.id}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
if is_reaction:
|
|
||||||
umcph.xp_count += settings.xp_per_reaction
|
|
||||||
else:
|
|
||||||
umcph.xp_count += settings.xp_per_message
|
|
||||||
|
|
||||||
self._umcphs.update_user_message_count_per_hour(umcph)
|
|
||||||
self._db.save_changes()
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(
|
|
||||||
__name__,
|
|
||||||
f"Cannot update user message count per hour with id {umcph.id}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
if umcph.xp_count is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return umcph.xp_count > settings.max_message_xp_per_hour
|
|
||||||
|
|
||||||
def get_ontime_for_user(self, user: User) -> float:
|
|
||||||
return round(
|
|
||||||
self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.id)
|
|
||||||
.where(lambda x: x.leaved_on is not None and x.joined_on is not None)
|
|
||||||
.sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600),
|
|
||||||
2,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def react_to_message_by_auto_role_rule(
|
|
||||||
self,
|
|
||||||
discord_channel_id: int,
|
|
||||||
discord_message_id: int,
|
|
||||||
rule: AutoRoleRule,
|
|
||||||
guild: discord.Guild,
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
guild: Guild = self._bot.guilds.where(lambda g: g == guild).single()
|
|
||||||
channel = guild.get_channel(discord_channel_id)
|
|
||||||
message = await channel.fetch_message(discord_message_id)
|
|
||||||
emoji = List(discord.Emoji, guild.emojis).where(lambda x: x.name == rule.emoji_name).single()
|
|
||||||
|
|
||||||
if emoji is None:
|
|
||||||
self._logger.debug(__name__, f"Emoji {rule.emoji_name} not found")
|
|
||||||
return
|
|
||||||
await message.add_reaction(emoji)
|
|
||||||
self._logger.debug(
|
|
||||||
__name__,
|
|
||||||
f"Added reaction {rule.emoji_name} to message: {discord_message_id}",
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(
|
|
||||||
__name__,
|
|
||||||
f"Cannot add reaction {rule.emoji_name} to message: {discord_message_id}",
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def check_default_role(self, member: Union[discord.User, discord.Member]):
|
|
||||||
try:
|
|
||||||
server = self._servers.get_server_by_discord_id(member.guild.id)
|
|
||||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.discord_id}")
|
|
||||||
|
|
||||||
if settings.default_role_id is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
default_role = member.guild.get_role(settings.default_role_id)
|
|
||||||
if default_role is None or default_role in member.roles:
|
|
||||||
return
|
|
||||||
|
|
||||||
await member.add_roles(default_role)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot check for default role for member {member.id}", e)
|
|
||||||
|
|
||||||
async def set_maintenance_mode(self, state: bool):
|
|
||||||
self._config.add_configuration(MAINTENANCE, state)
|
|
||||||
if state:
|
|
||||||
await self.presence_game("common.presence.maintenance")
|
|
||||||
else:
|
|
||||||
await self.presence_game("common.presence.running")
|
|
@@ -1,52 +0,0 @@
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
|
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|
||||||
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
|
|
||||||
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
|
|
||||||
from bot_data.model.server import Server
|
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
|
||||||
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
|
||||||
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigService:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
services: ServiceProviderABC,
|
|
||||||
technician_config_repo: TechnicianConfigRepositoryABC,
|
|
||||||
server_config_repo: ServerConfigRepositoryABC,
|
|
||||||
technician_seeder: TechnicianConfigSeeder,
|
|
||||||
server_seeder: ServerConfigSeeder,
|
|
||||||
):
|
|
||||||
self._config = config
|
|
||||||
self._services = services
|
|
||||||
self._technician_config_repo = technician_config_repo
|
|
||||||
self._technician_seeder = technician_seeder
|
|
||||||
self._server_config_repo = server_config_repo
|
|
||||||
|
|
||||||
self._server_seeder = server_seeder
|
|
||||||
|
|
||||||
async def reload_technician_config(self):
|
|
||||||
try:
|
|
||||||
technician_config = self._technician_config_repo.get_technician_config()
|
|
||||||
except Exception as e:
|
|
||||||
await self._technician_seeder.seed()
|
|
||||||
technician_config = self._technician_config_repo.get_technician_config()
|
|
||||||
|
|
||||||
self._config.add_configuration(TechnicianConfig, technician_config)
|
|
||||||
self._config.add_configuration(
|
|
||||||
FeatureFlagsSettings,
|
|
||||||
FeatureFlagsSettings(**technician_config.feature_flags),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def reload_server_config(self, server: Server):
|
|
||||||
if not self._server_config_repo.does_server_config_exists(server.id):
|
|
||||||
await self._server_seeder.seed()
|
|
||||||
|
|
||||||
server_config = self._server_config_repo.get_server_config_by_server(server.id)
|
|
||||||
self._config.add_configuration(
|
|
||||||
f"{type(server_config).__name__}_{server_config.server.discord_id}",
|
|
||||||
server_config,
|
|
||||||
)
|
|
@@ -1,421 +0,0 @@
|
|||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
import discord
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
|
||||||
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
|
|
||||||
|
|
||||||
def _check_known_users(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking KnownUsers table, {len(self._bot.users)}")
|
|
||||||
for u in self._bot.users:
|
|
||||||
u: discord.User = u
|
|
||||||
try:
|
|
||||||
if u.bot:
|
|
||||||
self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot")
|
|
||||||
continue
|
|
||||||
|
|
||||||
user = self._known_users.find_user_by_discord_id(u.id)
|
|
||||||
if user is not None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._logger.warn(__name__, f"Unknown user: {u.id}")
|
|
||||||
self._logger.debug(__name__, f"Add user: {u.id}")
|
|
||||||
self._known_users.add_user(KnownUser(u.id))
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
user = self._known_users.find_user_by_discord_id(u.id)
|
|
||||||
if user is None:
|
|
||||||
self._logger.fatal(__name__, f"Cannot add user: {u.id}")
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Added user: {u.id}")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get user", e)
|
|
||||||
|
|
||||||
def _check_servers(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking Servers table")
|
|
||||||
for g in self._bot.guilds:
|
|
||||||
g: discord.Guild = g
|
|
||||||
try:
|
|
||||||
server = self._servers.find_server_by_discord_id(g.id)
|
|
||||||
if server is not None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._logger.warn(__name__, f"Server not found in database: {g.id}")
|
|
||||||
self._logger.debug(__name__, f"Add server: {g.id}")
|
|
||||||
self._servers.add_server(Server(g.id))
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
server = self._servers.find_server_by_discord_id(g.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Cannot add server: {g.id}")
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Added server: {g.id}")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get server", 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_clients(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking Clients table")
|
|
||||||
for g in self._bot.guilds:
|
|
||||||
g: discord.Guild = g
|
|
||||||
try:
|
|
||||||
server: Server = self._servers.find_server_by_discord_id(g.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Server not found in database: {g.id}")
|
|
||||||
|
|
||||||
client = self._clients.find_client_by_server_id(server.id)
|
|
||||||
if client is not None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"Client for server {g.id} not found in database: {self._bot.user.id}",
|
|
||||||
)
|
|
||||||
self._logger.debug(__name__, f"Add client: {self._bot.user.id}")
|
|
||||||
self._clients.add_client(Client(self._bot.user.id, 0, 0, 0, 0, 0, server))
|
|
||||||
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 {g.id}",
|
|
||||||
)
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Added client: {g.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_users(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking Users table")
|
|
||||||
for g in self._bot.guilds:
|
|
||||||
g: discord.Guild = g
|
|
||||||
|
|
||||||
try:
|
|
||||||
server = self._servers.find_server_by_discord_id(g.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Server not found in database: {g.id}")
|
|
||||||
|
|
||||||
for u in g.members:
|
|
||||||
u: Union[discord.Member, discord.User] = u
|
|
||||||
if u.bot:
|
|
||||||
self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot")
|
|
||||||
continue
|
|
||||||
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(u.id, server.id)
|
|
||||||
if user is not None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._logger.warn(__name__, f"User not found in database: {u.id}")
|
|
||||||
self._logger.debug(__name__, f"Add user: {u.id}")
|
|
||||||
self._users.add_user(User(u.id, 0, 0, 0, None, server))
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Added User: {u.id}")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get User", e)
|
|
||||||
|
|
||||||
results = self._users.get_users()
|
|
||||||
if results is None or len(results) == 0:
|
|
||||||
self._logger.error(__name__, f"Table Users is empty!")
|
|
||||||
|
|
||||||
def _check_user_joins(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking UserJoinedServers table")
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
guild: discord.Guild = guild
|
|
||||||
|
|
||||||
server = self._servers.find_server_by_discord_id(guild.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
for u in guild.members:
|
|
||||||
u: discord.User = u
|
|
||||||
if u.bot:
|
|
||||||
self._logger.trace(__name__, f"User {u.id} is ignored, because its a bot")
|
|
||||||
continue
|
|
||||||
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(u.id, server.id)
|
|
||||||
if user is None:
|
|
||||||
self._logger.fatal(__name__, f"User not found in database: {u.id}")
|
|
||||||
|
|
||||||
join = self._user_joins.find_active_user_joined_server_by_user_id(user.id)
|
|
||||||
if join is not None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
m: discord.Member = u
|
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"Active UserJoinedServer not found in database: {guild.id}:{u.id}@{m.joined_at}",
|
|
||||||
)
|
|
||||||
self._logger.debug(
|
|
||||||
__name__,
|
|
||||||
f"Add UserJoinedServer: {guild.id}:{u.id}@{m.joined_at}",
|
|
||||||
)
|
|
||||||
self._user_joins.add_user_joined_server(
|
|
||||||
UserJoinedServer(user, self._dtp.transform(m.joined_at), None)
|
|
||||||
)
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Added UserJoinedServer: {u.id}")
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get UserJoinedServer", e)
|
|
||||||
|
|
||||||
results = self._users.get_users()
|
|
||||||
if results is None or len(results) == 0:
|
|
||||||
self._logger.error(__name__, f"Table Users is empty!")
|
|
||||||
|
|
||||||
joins = self._user_joins.get_user_joined_servers()
|
|
||||||
for join in joins:
|
|
||||||
join: UserJoinedServer = join
|
|
||||||
if join.user.server.discord_id != guild.id:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if join.leaved_on is not None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
dc_user = guild.get_member(join.user.discord_id)
|
|
||||||
if dc_user is None:
|
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"User {join.user.discord_id} already left the server.",
|
|
||||||
)
|
|
||||||
join.leaved_on = datetime.now()
|
|
||||||
self._user_joins.update_user_joined_server(join)
|
|
||||||
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
def _check_user_joins_vc(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking UserJoinedVoiceChannel table")
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
guild: discord.Guild = guild
|
|
||||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
|
|
||||||
|
|
||||||
server = self._servers.find_server_by_discord_id(guild.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
# close open voice states
|
|
||||||
for member in guild.members:
|
|
||||||
if member.bot:
|
|
||||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
|
||||||
continue
|
|
||||||
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
|
||||||
if user is None:
|
|
||||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
|
||||||
|
|
||||||
joins = self._user_joins_vc.find_active_user_joined_voice_channels_by_user_id(user.id)
|
|
||||||
if joins is None or len(joins) == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
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
|
|
||||||
for member in guild.members:
|
|
||||||
if member.bot:
|
|
||||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if member.voice is None or member.voice.channel.id in settings.afk_channel_ids:
|
|
||||||
continue
|
|
||||||
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
|
||||||
if user is None:
|
|
||||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
|
||||||
|
|
||||||
join = UserJoinedVoiceChannel(user, member.voice.channel.id, datetime.now())
|
|
||||||
self._user_joins_vc.add_user_joined_voice_channel(join)
|
|
||||||
self._db_context.save_changes()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get UserJoinedVoiceChannel", e)
|
|
||||||
|
|
||||||
def _check_user_joined_gs(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking UserJoinedGameServer table")
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
guild: discord.Guild = guild
|
|
||||||
|
|
||||||
server = self._servers.find_server_by_discord_id(guild.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
for member in guild.members:
|
|
||||||
if member.bot:
|
|
||||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
|
||||||
continue
|
|
||||||
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
|
||||||
if user is None:
|
|
||||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
|
||||||
|
|
||||||
joins = self._user_joined_gs.find_active_user_joined_game_servers_by_user_id(user.id)
|
|
||||||
if joins is None or len(joins) == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for join in joins:
|
|
||||||
self._logger.warn(
|
|
||||||
__name__,
|
|
||||||
f"Active UserJoinedGameServer found in database: {guild.id}:{member.id}@{join.joined_on}",
|
|
||||||
)
|
|
||||||
join.leaved_on = datetime.now()
|
|
||||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
|
|
||||||
|
|
||||||
if (
|
|
||||||
(join.leaved_on - join.joined_on).total_seconds() / 60 / 60
|
|
||||||
) > settings.max_voice_state_hours:
|
|
||||||
join.leaved_on = join.joined_on + timedelta(hours=settings.max_voice_state_hours)
|
|
||||||
|
|
||||||
self._user_joined_gs.update_user_joined_game_server(join)
|
|
||||||
if self._is_for_shutdown:
|
|
||||||
user.xp += round(join.time * settings.xp_per_ontime_hour)
|
|
||||||
self._users.update_user(user)
|
|
||||||
|
|
||||||
self._db_context.save_changes()
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Cannot get UserJoinedGameServer", e)
|
|
||||||
|
|
||||||
async def _check_for_user_achievements(self):
|
|
||||||
self._logger.debug(__name__, f"Start checking UserGotAchievement table")
|
|
||||||
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
server = self._servers.find_server_by_discord_id(guild.id)
|
|
||||||
if server is None:
|
|
||||||
self._logger.fatal(__name__, f"Server not found in database: {guild.id}")
|
|
||||||
|
|
||||||
for member in guild.members:
|
|
||||||
if member.bot:
|
|
||||||
self._logger.trace(__name__, f"User {member.id} is ignored, because its a bot")
|
|
||||||
continue
|
|
||||||
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
|
||||||
if user is None:
|
|
||||||
self._logger.fatal(__name__, f"User not found in database: {member.id}")
|
|
||||||
|
|
||||||
await self._achievements.validate_achievements_for_user(user)
|
|
||||||
|
|
||||||
async def _check_default_role(self):
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
for member in guild.members:
|
|
||||||
await self._client_utils.check_default_role(member)
|
|
||||||
|
|
||||||
def _check_for_bots(self):
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
server = self._servers.get_server_by_discord_id(guild.id)
|
|
||||||
|
|
||||||
for member in guild.members.where(lambda x: x.bot):
|
|
||||||
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.id)
|
|
||||||
if user is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for join in self._user_joins.get_user_joined_servers_by_user_id(user.id):
|
|
||||||
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()
|
|
||||||
|
|
||||||
async def check_data_integrity(self, is_for_shutdown=False):
|
|
||||||
if is_for_shutdown != self._is_for_shutdown:
|
|
||||||
self._is_for_shutdown = is_for_shutdown
|
|
||||||
|
|
||||||
await self._check_default_role()
|
|
||||||
self._check_known_users()
|
|
||||||
self._check_servers()
|
|
||||||
self._check_clients()
|
|
||||||
self._check_users()
|
|
||||||
self._check_user_joins()
|
|
||||||
self._check_user_joins_vc()
|
|
||||||
self._check_user_joined_gs()
|
|
||||||
await self._check_for_user_achievements()
|
|
||||||
self._check_for_bots()
|
|
@@ -1,200 +0,0 @@
|
|||||||
import asyncio
|
|
||||||
from typing import Union, Optional
|
|
||||||
|
|
||||||
import discord
|
|
||||||
from cpl_core.configuration.configuration_abc import ConfigurationABC
|
|
||||||
from cpl_core.database.context.database_context_abc import DatabaseContextABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
from discord import Interaction
|
|
||||||
from discord.ext.commands import Context
|
|
||||||
|
|
||||||
from bot_core.abc.message_service_abc import MessageServiceABC
|
|
||||||
from bot_core.helper.log_message_helper import LogMessageHelper
|
|
||||||
from bot_core.logging.message_logger import MessageLogger
|
|
||||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
|
||||||
from bot_data.model.server_config import ServerConfig
|
|
||||||
|
|
||||||
|
|
||||||
class MessageService(MessageServiceABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
logger: MessageLogger,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
clients: ClientRepositoryABC,
|
|
||||||
db: DatabaseContextABC,
|
|
||||||
):
|
|
||||||
self._config = config
|
|
||||||
self._logger = logger
|
|
||||||
self._bot = bot
|
|
||||||
self._clients = clients
|
|
||||||
self._db = db
|
|
||||||
|
|
||||||
async def delete_messages(self, messages: List[discord.Message], guild_id: int, without_tracking=False):
|
|
||||||
self._logger.debug(__name__, f"Try to delete {messages.count()} messages")
|
|
||||||
server_st: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
|
|
||||||
await asyncio.sleep(server_st.message_delete_timer)
|
|
||||||
for message in messages:
|
|
||||||
await self.delete_message(message, mass_delete=True, without_tracking=without_tracking)
|
|
||||||
self._logger.debug(__name__, "Deleting messages finished")
|
|
||||||
|
|
||||||
async def delete_message(self, message: discord.Message, mass_delete=False, without_tracking=False):
|
|
||||||
guild_id = (
|
|
||||||
message.guild.id
|
|
||||||
if message.guild is not None
|
|
||||||
else message.channel.guild.id
|
|
||||||
if message.channel is not None and message.channel.guild is not None
|
|
||||||
else message.reference.guild_id
|
|
||||||
if message.reference is not None and message.reference.guild_id is not None
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
|
|
||||||
server_st: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild_id}")
|
|
||||||
if not mass_delete:
|
|
||||||
await asyncio.sleep(server_st.message_delete_timer)
|
|
||||||
self._logger.debug(
|
|
||||||
__name__,
|
|
||||||
f"Try to delete message: {LogMessageHelper.get_log_string(message)}",
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
await message.delete()
|
|
||||||
await asyncio.sleep(server_st.message_delete_timer)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Deleting message failed", e)
|
|
||||||
else:
|
|
||||||
if not without_tracking:
|
|
||||||
self._clients.append_deleted_message_count(self._bot.user.id, guild_id, 1)
|
|
||||||
self._db.save_changes()
|
|
||||||
self._logger.info(__name__, f"Deleted message {message}")
|
|
||||||
|
|
||||||
async def send_channel_message(
|
|
||||||
self,
|
|
||||||
channel: discord.TextChannel,
|
|
||||||
message: Union[str, discord.Embed, list[discord.Embed]],
|
|
||||||
is_persistent: bool = False,
|
|
||||||
wait_before_delete: int = None,
|
|
||||||
without_tracking=False,
|
|
||||||
):
|
|
||||||
self._logger.debug(__name__, f"Try to send message\n\t{message}\n\tto: {channel}")
|
|
||||||
msg = None
|
|
||||||
try:
|
|
||||||
if isinstance(message, discord.Embed):
|
|
||||||
msg = await channel.send(embed=message)
|
|
||||||
elif isinstance(message, list):
|
|
||||||
msg = await channel.send(embeds=message)
|
|
||||||
else:
|
|
||||||
msg = await channel.send(message)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Send message to channel {channel.id} failed", e)
|
|
||||||
else:
|
|
||||||
self._logger.info(__name__, f"Sent message to channel {channel.id}")
|
|
||||||
if not without_tracking:
|
|
||||||
self._clients.append_sent_message_count(self._bot.user.id, channel.guild.id, 1)
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
if wait_before_delete is not None:
|
|
||||||
await asyncio.sleep(wait_before_delete)
|
|
||||||
|
|
||||||
if is_persistent:
|
|
||||||
return
|
|
||||||
|
|
||||||
await self.delete_message(msg, without_tracking)
|
|
||||||
|
|
||||||
async def send_dm_message(
|
|
||||||
self,
|
|
||||||
message: Union[str, discord.Embed],
|
|
||||||
receiver: Union[discord.User, discord.Member],
|
|
||||||
without_tracking=False,
|
|
||||||
):
|
|
||||||
self._logger.debug(__name__, f"Try to send message\n\t{message}\n\tto: {receiver}")
|
|
||||||
try:
|
|
||||||
if isinstance(message, discord.Embed):
|
|
||||||
msg = await receiver.send(embed=message)
|
|
||||||
else:
|
|
||||||
msg = await receiver.send(message)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Send message to user {receiver.id} failed", e)
|
|
||||||
else:
|
|
||||||
if not without_tracking:
|
|
||||||
self._clients.append_sent_message_count(self._bot.user.id, receiver.guild.id, 1)
|
|
||||||
self._db.save_changes()
|
|
||||||
self._logger.info(__name__, f"Sent message to user {receiver.id}")
|
|
||||||
|
|
||||||
async def send_ctx_msg(
|
|
||||||
self,
|
|
||||||
ctx: Context,
|
|
||||||
message: Union[str, discord.Embed],
|
|
||||||
file: discord.File = None,
|
|
||||||
is_persistent: bool = False,
|
|
||||||
is_public: bool = False,
|
|
||||||
wait_before_delete: int = None,
|
|
||||||
without_tracking=False,
|
|
||||||
) -> Optional[discord.Message]:
|
|
||||||
if ctx is None:
|
|
||||||
self._logger.warn(__name__, "Message context is empty")
|
|
||||||
self._logger.debug(__name__, f"Message: {message}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Try to send message\t\t{message}\n\tto: {ctx.channel}")
|
|
||||||
msg = None
|
|
||||||
try:
|
|
||||||
if isinstance(message, discord.Embed):
|
|
||||||
msg = await ctx.send(embed=message, file=file, ephemeral=not is_public)
|
|
||||||
else:
|
|
||||||
msg = await ctx.send(message, file=file, ephemeral=not is_public)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Send message to channel {ctx.channel.id} failed", e)
|
|
||||||
else:
|
|
||||||
self._logger.info(__name__, f"Sent message to channel {ctx.channel.id}")
|
|
||||||
if not without_tracking and ctx.guild is not None:
|
|
||||||
self._clients.append_sent_message_count(self._bot.user.id, ctx.guild.id, 1)
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
if wait_before_delete is not None:
|
|
||||||
await asyncio.sleep(wait_before_delete)
|
|
||||||
|
|
||||||
if is_persistent:
|
|
||||||
return msg
|
|
||||||
|
|
||||||
if ctx.guild is not None:
|
|
||||||
await self.delete_message(msg, without_tracking)
|
|
||||||
|
|
||||||
return msg
|
|
||||||
|
|
||||||
async def send_interaction_msg(
|
|
||||||
self,
|
|
||||||
interaction: Interaction,
|
|
||||||
message: Union[str, discord.Embed],
|
|
||||||
is_persistent: bool = False,
|
|
||||||
is_public: bool = False,
|
|
||||||
wait_before_delete: int = None,
|
|
||||||
without_tracking=False,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
if interaction is None:
|
|
||||||
self._logger.warn(__name__, "Message context is empty")
|
|
||||||
self._logger.debug(__name__, f"Message: {message}")
|
|
||||||
return
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Try to send message\t\t{message}\n\tto: {interaction.channel}")
|
|
||||||
try:
|
|
||||||
if isinstance(message, discord.Embed):
|
|
||||||
await interaction.response.send_message(embed=message, ephemeral=not is_public, **kwargs)
|
|
||||||
else:
|
|
||||||
await interaction.response.send_message(message, ephemeral=not is_public, **kwargs)
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Send message to channel {interaction.channel.id} failed", e)
|
|
||||||
else:
|
|
||||||
self._logger.info(__name__, f"Sent message to channel {interaction.channel.id}")
|
|
||||||
if not without_tracking and interaction.guild is not None:
|
|
||||||
self._clients.append_sent_message_count(self._bot.user.id, interaction.guild.id, 1)
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
if wait_before_delete is not None:
|
|
||||||
await asyncio.sleep(wait_before_delete)
|
|
||||||
|
|
||||||
if is_persistent:
|
|
||||||
return
|
|
||||||
|
|
||||||
await self.delete_message(await interaction.original_response(), without_tracking)
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_data"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_data.abc"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,52 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.achievement import Achievement
|
|
||||||
from bot_data.model.user_got_achievement import UserGotAchievement
|
|
||||||
|
|
||||||
|
|
||||||
class AchievementRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_achievements(self) -> List[Achievement]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_achievement_by_id(self, id: int) -> Achievement:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_achievements_by_server_id(self, server_id: int) -> List[Achievement]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_achievements_by_user_id(self, user_id: int) -> List[Achievement]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_got_achievements_by_achievement_id(self, achievement_id: int) -> List[Achievement]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_achievement(self, achievement: Achievement):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_achievement(self, achievement: Achievement):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_achievement(self, achievement: Achievement):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_user_got_achievement(self, join: UserGotAchievement):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_got_achievement(self, join: UserGotAchievement):
|
|
||||||
pass
|
|
@@ -1,39 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.api_key import ApiKey
|
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_api_keys(self) -> List[ApiKey]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_api_key(self, identifier: str, key: str) -> ApiKey:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_api_key_by_id(self, id: int) -> ApiKey:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_api_key_by_key(self, key: str) -> ApiKey:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_api_key(self, api_key: ApiKey):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_api_key(self, api_key: ApiKey):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_api_key(self, api_key: ApiKey):
|
|
||||||
pass
|
|
@@ -1,39 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.game_server import GameServer
|
|
||||||
|
|
||||||
|
|
||||||
class GameServerRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_game_servers(self) -> List[GameServer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_game_server_by_id(self, id: int) -> GameServer:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_game_servers_by_server_id(self, id: int) -> List[GameServer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_game_servers_by_api_key_id(self, id: int) -> List[GameServer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_game_server(self, game_server: GameServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_game_server(self, game_server: GameServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_game_server(self, game_server: GameServer):
|
|
||||||
pass
|
|
@@ -1,27 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
|
|
||||||
class HistoryTableABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
self._id = 0
|
|
||||||
self._deleted = False
|
|
||||||
self._date_from = datetime.now().isoformat()
|
|
||||||
self._date_to = datetime.now().isoformat()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def id(self) -> int:
|
|
||||||
return self._id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def deleted(self) -> bool:
|
|
||||||
return self._deleted
|
|
||||||
|
|
||||||
@property
|
|
||||||
def date_from(self) -> str:
|
|
||||||
return self._date_from
|
|
||||||
|
|
||||||
@property
|
|
||||||
def date_to(self) -> str:
|
|
||||||
return self._date_to
|
|
@@ -1,32 +0,0 @@
|
|||||||
import os
|
|
||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
|
||||||
from mysql.connector.cursor import MySQLCursorBuffered
|
|
||||||
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class MigrationABC(ABC):
|
|
||||||
name = None
|
|
||||||
prio = 0
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
@ServiceProviderABC.inject
|
|
||||||
def __init__(self, db: DBContext):
|
|
||||||
self._cursor: MySQLCursorBuffered = db.cursor
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def upgrade(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def downgrade(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _exec(self, self_file: str, file: str):
|
|
||||||
path = f"{os.path.dirname(os.path.realpath(self_file))}/db_history_scripts"
|
|
||||||
sql = open(f"{path}/{file}").read()
|
|
||||||
|
|
||||||
for statement in sql.split("\n\n"):
|
|
||||||
self._cursor.execute(statement + ";")
|
|
@@ -1,59 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from bot_data.model.server_afk_channel_ids_config import ServerAFKChannelIdsConfig
|
|
||||||
from bot_data.model.server_config import ServerConfig
|
|
||||||
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
|
|
||||||
|
|
||||||
|
|
||||||
class ServerConfigRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def does_server_config_exists(self, server_id: int) -> bool:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_server_config_by_server(self, server_id: int) -> ServerConfig:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_server_config_by_id(self, config_id: int) -> ServerConfig:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_server_config(self, server_config: ServerConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_server_config(self, server_config: ServerConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_server_config(self, server_config: ServerConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_server_team_role_id_config(self, server_team_role_id: ServerTeamRoleIdsConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_server_afk_channel_config(self, server_afk_channel: ServerAFKChannelIdsConfig):
|
|
||||||
pass
|
|
@@ -1,39 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.short_role_name import ShortRoleName
|
|
||||||
|
|
||||||
|
|
||||||
class ShortRoleNameRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_short_role_names(self) -> List[ShortRoleName]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_short_role_name_by_id(self, id: int) -> ShortRoleName:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_short_role_names_by_role_id(self, role_id: int) -> List[ShortRoleName]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_short_role_names_by_server_id(self, id: int) -> List[ShortRoleName]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_short_role_name(self, short_role_name: ShortRoleName):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_short_role_name(self, short_role_name: ShortRoleName):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_short_role_name(self, short_role_name: ShortRoleName):
|
|
||||||
pass
|
|
@@ -1,32 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.steam_special_offer import SteamSpecialOffer
|
|
||||||
|
|
||||||
|
|
||||||
class SteamSpecialOfferRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_steam_special_offers(self) -> List[SteamSpecialOffer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_steam_special_offer_by_name(self, name: str) -> SteamSpecialOffer:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
pass
|
|
@@ -1,15 +0,0 @@
|
|||||||
from abc import abstractmethod
|
|
||||||
|
|
||||||
from cpl_core.database import TableABC
|
|
||||||
|
|
||||||
|
|
||||||
class TableWithIdABC(TableABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
self.__init__()
|
|
||||||
|
|
||||||
self._id = 0
|
|
||||||
|
|
||||||
@property
|
|
||||||
def id(self) -> int:
|
|
||||||
return self._id
|
|
@@ -1,55 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
|
||||||
from bot_data.model.technician_id_config import TechnicianIdConfig
|
|
||||||
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
|
|
||||||
|
|
||||||
|
|
||||||
class TechnicianConfigRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def does_technician_config_exists(self) -> bool:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_technician_config(self) -> TechnicianConfig:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_technician_config(self, technician_config: TechnicianConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_technician_config(self, technician_config: TechnicianConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_technician_config(self, technician_config: TechnicianConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_technician_id_config(self, technician_id: TechnicianIdConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_technician_id_config(self, technician_id: TechnicianIdConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_technician_id_config(self, technician_id: TechnicianIdConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_technician_ping_url_config(self, technician_ping_url: TechnicianPingUrlConfig):
|
|
||||||
pass
|
|
@@ -1,51 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.user_game_ident import UserGameIdent
|
|
||||||
|
|
||||||
|
|
||||||
class UserGameIdentRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_game_idents(self) -> List[UserGameIdent]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_game_idents_by_game_server_id(self, id: int) -> List[UserGameIdent]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_game_ident_by_id(self, id: int) -> UserGameIdent:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_game_ident_by_ident(self, ident: str) -> UserGameIdent:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_user_game_ident_by_ident(self, ident: str) -> UserGameIdent:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_game_idents_by_user_id(self, user_id: int) -> List[UserGameIdent]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_user_game_ident(self, user_game_ident: UserGameIdent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_user_game_ident(self, user_game_ident: UserGameIdent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_game_ident(self, user_game_ident: UserGameIdent):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_game_ident_by_user_id(self, user_id: int):
|
|
||||||
pass
|
|
@@ -1,52 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.user_joined_game_server import UserJoinedGameServer
|
|
||||||
|
|
||||||
|
|
||||||
class UserJoinedGameServerRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_joined_game_servers(self) -> List[UserJoinedGameServer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_joined_game_server_by_id(self, id: int) -> UserJoinedGameServer:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_joined_game_servers_by_user_id(self, user_id: int) -> List[UserJoinedGameServer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_active_user_joined_game_server_by_user_id(self, user_id: int) -> UserJoinedGameServer:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_active_user_joined_game_server_by_user_id(self, user_id: int) -> Optional[UserJoinedGameServer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_active_user_joined_game_servers_by_user_id(self, user_id: int) -> List[Optional[UserJoinedGameServer]]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_user_joined_game_server(self, user_joined_game_server: UserJoinedGameServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_user_joined_game_server(self, user_joined_game_server: UserJoinedGameServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_joined_game_server(self, user_joined_game_server: UserJoinedGameServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_joined_game_server_by_user_id(self, user_id: int):
|
|
||||||
pass
|
|
@@ -1,49 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.user_message_count_per_hour import UserMessageCountPerHour
|
|
||||||
|
|
||||||
|
|
||||||
class UserMessageCountPerHourRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_message_count_per_hours(self) -> List[UserMessageCountPerHour]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_user_message_count_per_hour_by_user_id(self, user_id: int) -> Optional[UserMessageCountPerHour]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_message_count_per_hour_by_user_id_and_date(
|
|
||||||
self, user_id: int, date: datetime
|
|
||||||
) -> Optional[UserMessageCountPerHour]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_user_message_count_per_hour_by_user_id_and_date(
|
|
||||||
self, user_id: int, date: datetime
|
|
||||||
) -> Optional[UserMessageCountPerHour]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_user_message_count_per_hour(self, umcph: UserMessageCountPerHour):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_user_message_count_per_hour(self, umcph: UserMessageCountPerHour):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_message_count_per_hour(self, umcph: UserMessageCountPerHour):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_message_count_per_hour_by_user_id(self, user_id: int):
|
|
||||||
pass
|
|
@@ -1,52 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.user import User
|
|
||||||
|
|
||||||
|
|
||||||
class UserRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_users(self) -> List[User]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_by_id(self, id: int) -> User:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_user_by_id(self, id: int) -> Optional[User]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_users_by_discord_id(self, discord_id: int) -> List[User]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_users_by_server_id(self, server_id: int) -> List[User]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def find_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> Optional[User]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_user(self, user: User):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_user(self, user: User):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user(self, user: User):
|
|
||||||
pass
|
|
@@ -1,35 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.user_warnings import UserWarnings
|
|
||||||
|
|
||||||
|
|
||||||
class UserWarningsRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_warnings(self) -> List[UserWarnings]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_warnings_by_id(self, id: int) -> UserWarnings:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_user_warnings_by_user_id(self, user_id: int) -> List[UserWarnings]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_user_warnings(self, user_warnings: UserWarnings):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_user_warnings(self, user_warnings: UserWarnings):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_user_warnings(self, user_warnings: UserWarnings):
|
|
||||||
pass
|
|
@@ -1,121 +0,0 @@
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
|
||||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
|
||||||
|
|
||||||
from bot_core.abc.module_abc import ModuleABC
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
|
|
||||||
from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC
|
|
||||||
from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC
|
|
||||||
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
|
|
||||||
from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
|
||||||
from bot_data.abc.data_seeder_abc import DataSeederABC
|
|
||||||
from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC
|
|
||||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
|
||||||
from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
|
||||||
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
|
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
|
||||||
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
|
|
||||||
from bot_data.abc.steam_special_offer_repository_abc import (
|
|
||||||
SteamSpecialOfferRepositoryABC,
|
|
||||||
)
|
|
||||||
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
|
|
||||||
from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC
|
|
||||||
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_message_count_per_hour_repository_abc import (
|
|
||||||
UserMessageCountPerHourRepositoryABC,
|
|
||||||
)
|
|
||||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
|
||||||
from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC
|
|
||||||
from bot_data.service.achievements_repository_service import (
|
|
||||||
AchievementRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.api_key_repository_service import ApiKeyRepositoryService
|
|
||||||
from bot_data.service.auth_user_repository_service import AuthUserRepositoryService
|
|
||||||
from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService
|
|
||||||
from bot_data.service.cache_service import CacheService
|
|
||||||
from bot_data.service.client_repository_service import ClientRepositoryService
|
|
||||||
from bot_data.service.game_server_repository_service import GameServerRepositoryService
|
|
||||||
from bot_data.service.known_user_repository_service import KnownUserRepositoryService
|
|
||||||
from bot_data.service.level_repository_service import LevelRepositoryService
|
|
||||||
from bot_data.service.seeder_service import SeederService
|
|
||||||
from bot_data.service.server_config_repository_service import (
|
|
||||||
ServerConfigRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
|
||||||
from bot_data.service.server_repository_service import ServerRepositoryService
|
|
||||||
from bot_data.service.short_role_name_repository_service import (
|
|
||||||
ShortRoleNameRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.steam_special_offer_repository_service import (
|
|
||||||
SteamSpecialOfferRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.technician_config_repository_service import (
|
|
||||||
TechnicianConfigRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
|
||||||
from bot_data.service.user_game_ident_repository_service import (
|
|
||||||
UserGameIdentRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.user_joined_game_server_repository_service import (
|
|
||||||
UserJoinedGameServerRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.user_joined_server_repository_service import (
|
|
||||||
UserJoinedServerRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.user_joined_voice_channel_repository_service import (
|
|
||||||
UserJoinedVoiceChannelRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.user_message_count_per_hour_repository_service import (
|
|
||||||
UserMessageCountPerHourRepositoryService,
|
|
||||||
)
|
|
||||||
from bot_data.service.user_repository_service import UserRepositoryService
|
|
||||||
from bot_data.service.user_warnings_repository_service import (
|
|
||||||
UserWarningsRepositoryService,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DataModule(ModuleABC):
|
|
||||||
def __init__(self, dc: DiscordCollectionABC):
|
|
||||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.data_module)
|
|
||||||
|
|
||||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
|
||||||
services.add_singleton(CacheService)
|
|
||||||
|
|
||||||
services.add_transient(ApiKeyRepositoryABC, ApiKeyRepositoryService)
|
|
||||||
services.add_transient(AuthUserRepositoryABC, AuthUserRepositoryService)
|
|
||||||
services.add_transient(ServerRepositoryABC, ServerRepositoryService)
|
|
||||||
services.add_transient(UserRepositoryABC, UserRepositoryService)
|
|
||||||
services.add_transient(ClientRepositoryABC, ClientRepositoryService)
|
|
||||||
services.add_transient(KnownUserRepositoryABC, KnownUserRepositoryService)
|
|
||||||
services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService)
|
|
||||||
services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService)
|
|
||||||
services.add_transient(UserJoinedGameServerRepositoryABC, UserJoinedGameServerRepositoryService)
|
|
||||||
services.add_transient(AutoRoleRepositoryABC, AutoRoleRepositoryService)
|
|
||||||
services.add_transient(LevelRepositoryABC, LevelRepositoryService)
|
|
||||||
services.add_transient(UserWarningsRepositoryABC, UserWarningsRepositoryService)
|
|
||||||
services.add_transient(
|
|
||||||
UserMessageCountPerHourRepositoryABC,
|
|
||||||
UserMessageCountPerHourRepositoryService,
|
|
||||||
)
|
|
||||||
services.add_transient(GameServerRepositoryABC, GameServerRepositoryService)
|
|
||||||
services.add_transient(UserGameIdentRepositoryABC, UserGameIdentRepositoryService)
|
|
||||||
services.add_transient(AchievementRepositoryABC, AchievementRepositoryService)
|
|
||||||
services.add_transient(TechnicianConfigRepositoryABC, TechnicianConfigRepositoryService)
|
|
||||||
services.add_transient(ServerConfigRepositoryABC, ServerConfigRepositoryService)
|
|
||||||
services.add_transient(ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService)
|
|
||||||
services.add_transient(SteamSpecialOfferRepositoryABC, SteamSpecialOfferRepositoryService)
|
|
||||||
|
|
||||||
services.add_transient(SeederService)
|
|
||||||
services.add_transient(DataSeederABC, TechnicianConfigSeeder)
|
|
||||||
services.add_transient(DataSeederABC, ServerConfigSeeder)
|
|
@@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "bot_data.migration"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.2.0"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="2", micro="0")
|
|
@@ -1,127 +0,0 @@
|
|||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class AchievementsMigration(MigrationABC):
|
|
||||||
name = "1.1.0_AchievementsMigration"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._cursor = db.cursor
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `Achievements` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`Name` VARCHAR(255) NOT NULL,
|
|
||||||
`Description` VARCHAR(255) NOT NULL,
|
|
||||||
`Attribute` VARCHAR(255) NOT NULL,
|
|
||||||
`Operator` VARCHAR(255) NOT NULL,
|
|
||||||
`Value` VARCHAR(255) NOT NULL,
|
|
||||||
`ServerId` BIGINT,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`),
|
|
||||||
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `AchievementsHistory`
|
|
||||||
(
|
|
||||||
`Id` BIGINT(20) NOT NULL,
|
|
||||||
`Name` VARCHAR(255) NOT NULL,
|
|
||||||
`Description` VARCHAR(255) NOT NULL,
|
|
||||||
`Attribute` VARCHAR(255) NOT NULL,
|
|
||||||
`Operator` VARCHAR(255) NOT NULL,
|
|
||||||
`Value` VARCHAR(255) NOT NULL,
|
|
||||||
`ServerId` BIGINT,
|
|
||||||
`Deleted` BOOL DEFAULT FALSE,
|
|
||||||
`DateFrom` DATETIME(6) NOT NULL,
|
|
||||||
`DateTo` DATETIME(6) NOT NULL
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `UserGotAchievements` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`UserId` BIGINT,
|
|
||||||
`AchievementId` BIGINT,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`),
|
|
||||||
FOREIGN KEY (`UserId`) REFERENCES `Users`(`UserId`),
|
|
||||||
FOREIGN KEY (`AchievementId`) REFERENCES `Achievements`(`Id`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# A join table history between users and achievements is not necessary.
|
|
||||||
|
|
||||||
self._cursor.execute(str(f"""ALTER TABLE Users ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
|
||||||
self._cursor.execute(str(f"""ALTER TABLE Users ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
|
||||||
self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
|
||||||
self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
|
|
||||||
|
|
||||||
self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;"""))
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TRIGGER `TR_AchievementsUpdate`
|
|
||||||
AFTER UPDATE
|
|
||||||
ON `Achievements`
|
|
||||||
FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO `AchievementsHistory` (
|
|
||||||
`Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `DateFrom`, `DateTo`
|
|
||||||
)
|
|
||||||
VALUES (
|
|
||||||
OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;"""))
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TRIGGER `TR_AchievementsDelete`
|
|
||||||
AFTER DELETE
|
|
||||||
ON `Achievements`
|
|
||||||
FOR EACH ROW
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO `AchievementsHistory` (
|
|
||||||
`Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `Deleted`, `DateFrom`, `DateTo`
|
|
||||||
)
|
|
||||||
VALUES (
|
|
||||||
OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._cursor.execute("DROP TABLE `Achievements`;")
|
|
||||||
|
|
||||||
self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN MessageCount;"""))
|
|
||||||
self._cursor.execute(str(f"""ALTER TABLE Users DROP COLUMN ReactionCount;"""))
|
|
@@ -1,38 +0,0 @@
|
|||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyMigration(MigrationABC):
|
|
||||||
name = "1.0.0_ApiKeyMigration"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._cursor = db.cursor
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `ApiKeys` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`Identifier` VARCHAR(255) NOT NULL,
|
|
||||||
`Key` VARCHAR(255) NOT NULL,
|
|
||||||
`CreatorId` BIGINT NULL,
|
|
||||||
`CreatedAt` DATETIME(6),
|
|
||||||
`LastModifiedAt` DATETIME(6),
|
|
||||||
PRIMARY KEY(`Id`),
|
|
||||||
FOREIGN KEY (`CreatorId`) REFERENCES `Users`(`UserId`),
|
|
||||||
CONSTRAINT UC_Identifier_Key UNIQUE (`Identifier`,`Key`),
|
|
||||||
CONSTRAINT UC_Key UNIQUE (`Key`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._cursor.execute("DROP TABLE `ApiKeys`;")
|
|
@@ -1,33 +0,0 @@
|
|||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class AutoRoleFix1Migration(MigrationABC):
|
|
||||||
name = "0.3.0_AutoRoleFixMigration"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._cursor = db.cursor
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE AutoRoles ADD DiscordChannelId BIGINT NOT NULL AFTER ServerId;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE AutoRoles DROP COLUMN DiscordChannelId;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
@@ -1,84 +0,0 @@
|
|||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class BirthdayMigration(MigrationABC):
|
|
||||||
name = "1.2.0_BirthdayMigration"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._cursor = db.cursor
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE Users
|
|
||||||
ADD Birthday DATE NULL AFTER MessageCount;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE UsersHistory
|
|
||||||
ADD Birthday DATE NULL AFTER MessageCount;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._exec(__file__, "users.sql")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_Server
|
|
||||||
ADD XpForBirthday BIGINT(20) NOT NULL DEFAULT 0 AFTER XpPerAchievement;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_ServerHistory
|
|
||||||
ADD XpForBirthday BIGINT(20) NOT NULL DEFAULT 0 AFTER XpPerAchievement;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._exec(__file__, "config/server.sql")
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE Users DROP COLUMN Birthday;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE UsersHistory DROP COLUMN Birthday;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_Server DROP COLUMN XpForBirthday;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_ServerHistory DROP COLUMN XpForBirthday;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
@@ -1,29 +0,0 @@
|
|||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigFeatureFlagsMigration(MigrationABC):
|
|
||||||
name = "1.1.0_ConfigFeatureFlagsMigration"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._cursor = db.cursor
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str("""ALTER TABLE CFG_Technician ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER CacheMaxMessages;""")
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str("""ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT ('{}') AFTER LoginMessageChannelId;""")
|
|
||||||
)
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running downgrade")
|
|
||||||
self._cursor.execute("ALTER TABLE CFG_Technician DROP COLUMN FeatureFlags;")
|
|
||||||
self._cursor.execute("ALTER TABLE CFG_Server DROP COLUMN FeatureFlags;")
|
|
@@ -1,145 +0,0 @@
|
|||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigMigration(MigrationABC):
|
|
||||||
name = "1.1.0_ConfigMigration"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
self._server_upgrade()
|
|
||||||
self._technician_upgrade()
|
|
||||||
|
|
||||||
self._exec(__file__, "config/server.sql")
|
|
||||||
self._exec(__file__, "config/server_afk_channels.sql")
|
|
||||||
self._exec(__file__, "config/server_team_roles.sql")
|
|
||||||
self._exec(__file__, "config/technician.sql")
|
|
||||||
self._exec(__file__, "config/technician_ids.sql")
|
|
||||||
self._exec(__file__, "config/technician_ping_urls.sql")
|
|
||||||
|
|
||||||
def _server_upgrade(self):
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `CFG_Server` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`MessageDeleteTimer` BIGINT NOT NULL DEFAULT 6,
|
|
||||||
`NotificationChatId` BIGINT NOT NULL,
|
|
||||||
`MaxVoiceStateHours` BIGINT NOT NULL DEFAULT 6,
|
|
||||||
`XpPerMessage` BIGINT NOT NULL DEFAULT 1,
|
|
||||||
`XpPerReaction` BIGINT NOT NULL DEFAULT 1,
|
|
||||||
`MaxMessageXpPerHour` BIGINT NOT NULL DEFAULT 20,
|
|
||||||
`XpPerOntimeHour` BIGINT NOT NULL DEFAULT 10,
|
|
||||||
`XpPerEventParticipation` BIGINT NOT NULL DEFAULT 10,
|
|
||||||
`XpPerAchievement` BIGINT NOT NULL DEFAULT 10,
|
|
||||||
`AFKCommandChannelId` BIGINT NOT NULL,
|
|
||||||
`HelpVoiceChannelId` BIGINT NOT NULL,
|
|
||||||
`TeamChannelId` BIGINT NOT NULL,
|
|
||||||
`LoginMessageChannelId` BIGINT NOT NULL,
|
|
||||||
`ServerId` BIGINT NOT NULL,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`),
|
|
||||||
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `CFG_ServerAFKChannelIds` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`ChannelId` BIGINT NOT NULL,
|
|
||||||
`ServerId` BIGINT NOT NULL,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`),
|
|
||||||
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `CFG_ServerTeamRoleIds` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`RoleId` BIGINT NOT NULL,
|
|
||||||
`TeamMemberType` ENUM('Moderator', 'Admin') NOT NULL,
|
|
||||||
`ServerId` BIGINT NOT NULL,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`),
|
|
||||||
FOREIGN KEY (`ServerId`) REFERENCES `Servers`(`ServerId`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def _technician_upgrade(self):
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `CFG_Technician` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`HelpCommandReferenceUrl` VARCHAR(255) NOT NULL,
|
|
||||||
`WaitForRestart` BIGINT NOT NULL DEFAULT 8,
|
|
||||||
`WaitForShutdown` BIGINT NOT NULL DEFAULT 8,
|
|
||||||
`CacheMaxMessages` BIGINT NOT NULL DEFAULT 1000000,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `CFG_TechnicianPingUrls` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`URL` VARCHAR(255) NOT NULL,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `CFG_TechnicianIds` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`TechnicianId` BIGINT NOT NULL,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running downgrade")
|
|
||||||
self._server_downgrade()
|
|
||||||
self._technician_downgrade()
|
|
||||||
|
|
||||||
def _server_downgrade(self):
|
|
||||||
self._cursor.execute("DROP TABLE `CFG_Server`;")
|
|
||||||
|
|
||||||
def _technician_downgrade(self):
|
|
||||||
self._cursor.execute("DROP TABLE `CFG_Technician`;")
|
|
||||||
self._cursor.execute("DROP TABLE `CFG_TechnicianPingUrls`;")
|
|
||||||
self._cursor.execute("DROP TABLE `CFG_TechnicianIds`;")
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user