diff --git a/src/bot/bot.json b/src/bot/bot.json index 8bbcdf43..64495674 100644 --- a/src/bot/bot.json +++ b/src/bot/bot.json @@ -45,6 +45,7 @@ ], "PackageData": {}, "ProjectReferences": [ + "../bot_api/bot-api.json", "../bot_core/bot-core.json", "../bot_data/bot-data.json", "../modules/base/base.json", diff --git a/src/bot/translation/de.json b/src/bot/translation/de.json index 910de717..03b69e95 100644 --- a/src/bot/translation/de.json +++ b/src/bot/translation/de.json @@ -152,5 +152,13 @@ "database": {}, "permission": { } + }, + "api": { + "api": { + "test_mail": { + "subject": "Krümmelmonster Web Interface Test-Mail", + "message": "Dies ist eine Test-Mail vom Krümmelmonster Web Interface\nGesendet von {}-{}" + } + } } } \ No newline at end of file diff --git a/src/bot_api/__init__.py b/src/bot_api/__init__.py index ad5eca30..99097c73 100644 --- a/src/bot_api/__init__.py +++ b/src/bot_api/__init__.py @@ -1 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +bot Keksdose bot +~~~~~~~~~~~~~~~~~~~ + +Discord bot for the Keksdose discord Server + +:copyright: (c) 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'bot_api' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2022 sh-edraft.de' +__version__ = '0.2.3' + +from collections import namedtuple + + # imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='0', minor='2', micro='3') diff --git a/src/bot_api/abc/__init__.py b/src/bot_api/abc/__init__.py new file mode 100644 index 00000000..38bf68b7 --- /dev/null +++ b/src/bot_api/abc/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +bot Keksdose bot +~~~~~~~~~~~~~~~~~~~ + +Discord bot for the Keksdose discord Server + +:copyright: (c) 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'bot_api.abc' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2022 sh-edraft.de' +__version__ = '0.2.3' + +from collections import namedtuple + + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='0', minor='2', micro='3') diff --git a/src/bot_api/abc/dto_abc.py b/src/bot_api/abc/dto_abc.py new file mode 100644 index 00000000..58b458ad --- /dev/null +++ b/src/bot_api/abc/dto_abc.py @@ -0,0 +1,13 @@ +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 diff --git a/src/bot_api/api_module.py b/src/bot_api/api_module.py index 91f91794..3f26d80c 100644 --- a/src/bot_api/api_module.py +++ b/src/bot_api/api_module.py @@ -1,6 +1,9 @@ +import os + from cpl_core.configuration import ConfigurationABC from cpl_core.dependency_injection import ServiceCollectionABC from cpl_core.environment import ApplicationEnvironmentABC +from cpl_core.mailing import EMailClientABC, EMailClient from cpl_discord.service.discord_collection_abc import DiscordCollectionABC from flask import Flask @@ -17,9 +20,16 @@ class ApiModule(ModuleABC): ModuleABC.__init__(self, dc, FeatureFlagsEnum.api_module) def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): - pass + cwd = env.working_directory + env.set_working_directory(os.path.dirname(os.path.realpath(__file__))) + config.add_json_file(f'config/apisettings.json', optional=False) + config.add_json_file(f'config/apisettings.{env.environment_name}.json', optional=True) + config.add_json_file(f'config/apisettings.{env.host_name}.json', optional=True) + env.set_working_directory(cwd) def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + services.add_singleton(EMailClientABC, EMailClient) + services.add_singleton(ApiThread) services.add_singleton(Flask, Api) diff --git a/src/bot_api/config/apisettings.development.json b/src/bot_api/config/apisettings.development.json new file mode 100644 index 00000000..534e5087 --- /dev/null +++ b/src/bot_api/config/apisettings.development.json @@ -0,0 +1,8 @@ +{ + "EMailClientSettings": { + "Host": "mail.sh-edraft.de", + "Port": "587", + "UserName": "dev-srv@sh-edraft.de", + "Credentials": "RmBOQX1eNFYiYjgsSid3fV1nelc2WA==" + } +} \ No newline at end of file diff --git a/src/bot_api/config/apisettings.edrafts-lapi.json b/src/bot_api/config/apisettings.edrafts-lapi.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/src/bot_api/config/apisettings.edrafts-lapi.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/bot_api/config/apisettings.edrafts-pc-ubuntu.json b/src/bot_api/config/apisettings.edrafts-pc-ubuntu.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/src/bot_api/config/apisettings.edrafts-pc-ubuntu.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/bot_api/config/apisettings.json b/src/bot_api/config/apisettings.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/src/bot_api/config/apisettings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/bot_api/config/apisettings.production.json b/src/bot_api/config/apisettings.production.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/src/bot_api/config/apisettings.production.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/bot_api/config/apisettings.staging.json b/src/bot_api/config/apisettings.staging.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/src/bot_api/config/apisettings.staging.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/bot_api/config/appsettings.PC-Nick.json b/src/bot_api/config/appsettings.PC-Nick.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/src/bot_api/config/appsettings.PC-Nick.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/bot_api/configuration/__init__.py b/src/bot_api/configuration/__init__.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/src/bot_api/configuration/__init__.py @@ -0,0 +1 @@ +# imports diff --git a/src/bot_api/configuration/api_settings.py b/src/bot_api/configuration/api_settings.py new file mode 100644 index 00000000..e50f25fa --- /dev/null +++ b/src/bot_api/configuration/api_settings.py @@ -0,0 +1,23 @@ +import traceback + +from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC +from cpl_core.console import Console + + +class APISettings(ConfigurationModelABC): + + def __init__(self): + ConfigurationModelABC.__init__(self) + + self._redirect_to_https = False + + @property + def redirect_to_https(self) -> bool: + return self._redirect_to_https + + def from_dict(self, settings: dict): + try: + self._redirect_to_https = bool(settings['RedirectToHTTPS']) + except Exception as e: + Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') + Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') diff --git a/src/bot_api/configuration/version_settings.py b/src/bot_api/configuration/version_settings.py new file mode 100644 index 00000000..ef1af9b6 --- /dev/null +++ b/src/bot_api/configuration/version_settings.py @@ -0,0 +1,55 @@ +from typing import Optional + +from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC +from cpl_cli.configuration.version_settings_name_enum import VersionSettingsNameEnum + + +class VersionSettings(ConfigurationModelABC): + + def __init__( + self, + major: str = None, + minor: str = None, + micro: str = None + ): + ConfigurationModelABC.__init__(self) + + self._major: Optional[str] = major + self._minor: Optional[str] = minor + self._micro: Optional[str] = micro + + @property + def major(self) -> str: + return self._major + + @property + def minor(self) -> str: + return self._minor + + @property + def micro(self) -> str: + return self._micro + + def to_str(self) -> str: + if self._micro is None: + return f'{self._major}.{self._minor}' + else: + return f'{self._major}.{self._minor}.{self._micro}' + + def from_dict(self, settings: dict): + self._major = settings[VersionSettingsNameEnum.major.value] + self._minor = settings[VersionSettingsNameEnum.minor.value] + micro = settings[VersionSettingsNameEnum.micro.value] + if micro != '': + self._micro = micro + + def to_dict(self) -> dict: + version = { + VersionSettingsNameEnum.major.value: self._major, + VersionSettingsNameEnum.minor.value: self._minor, + } + + if self._micro is not None: + version[VersionSettingsNameEnum.micro.value] = self._micro + + return version diff --git a/src/bot_api/controller/__init__.py b/src/bot_api/controller/__init__.py index e69de29b..44c37e5c 100644 --- a/src/bot_api/controller/__init__.py +++ b/src/bot_api/controller/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +bot Keksdose bot +~~~~~~~~~~~~~~~~~~~ + +Discord bot for the Keksdose discord Server + +:copyright: (c) 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'bot_api.controller' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2022 sh-edraft.de' +__version__ = '0.2.3' + +from collections import namedtuple + + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='0', minor='2', micro='3') diff --git a/src/bot_api/controller/api_controller.py b/src/bot_api/controller/api_controller.py index 9c714166..e17103e6 100644 --- a/src/bot_api/controller/api_controller.py +++ b/src/bot_api/controller/api_controller.py @@ -1,7 +1,14 @@ +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 bot_api.api import Api 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 @@ -9,14 +16,57 @@ class ApiController: def __init__( self, + config: ConfigurationABC, + env: ApplicationEnvironmentABC, logger: ApiLogger, t: TranslatePipe, - api: Api + api: Api, + mail_settings: EMailClientSettings, + mailer: EMailClientABC ): + self._config = config + self._env = env self._logger = logger self._t = t self._api = api + self._mail_settings = mail_settings + self._mailer = mailer - @Route.route('/api/hello-world') - def hello_world(self): - return self._t.transform('common.hello_world') + @Route.route('/api/api-version') + def api_version(self): + import bot_api + version = bot_api.version_info + return VersionDTO(version.major, version.minor, version.micro).to_dict() + + @Route.route('/api/settings') + def settings(self): + # TODO: Authentication + import bot_api + version = bot_api.version_info + + return SettingsDTO( + '', + VersionDTO(version.major, version.minor, version.micro), + os.path.abspath(os.path.join(self._env.working_directory, 'config')), + '', + '/', + 0, + 0, + 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.route('/api/send-test-mail/') + def send_test_mail(self, email: str): + # TODO: Authentication + 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) diff --git a/src/bot_api/controller/api_route.py b/src/bot_api/controller/api_route.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/bot_api/logging/__init__.py b/src/bot_api/logging/__init__.py index e69de29b..d7b9d180 100644 --- a/src/bot_api/logging/__init__.py +++ b/src/bot_api/logging/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +bot Keksdose bot +~~~~~~~~~~~~~~~~~~~ + +Discord bot for the Keksdose discord Server + +:copyright: (c) 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'bot_api.logging' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2022 sh-edraft.de' +__version__ = '0.2.3' + +from collections import namedtuple + + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='0', minor='2', micro='3') diff --git a/src/bot_api/model/__init__.py b/src/bot_api/model/__init__.py new file mode 100644 index 00000000..da73f223 --- /dev/null +++ b/src/bot_api/model/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +bot Keksdose bot +~~~~~~~~~~~~~~~~~~~ + +Discord bot for the Keksdose discord Server + +:copyright: (c) 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'bot_api.model' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2022 sh-edraft.de' +__version__ = '0.2.3' + +from collections import namedtuple + + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='0', minor='2', micro='3') diff --git a/src/bot_api/model/settings_dto.py b/src/bot_api/model/settings_dto.py new file mode 100644 index 00000000..6d72245b --- /dev/null +++ b/src/bot_api/model/settings_dto.py @@ -0,0 +1,71 @@ +import traceback + +from cpl_core.console import Console + +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 = '' + self._api_version = VersionDTO() + self._config_path = '' + self._web_base_url = '' + self._api_base_url = '' + + self._token_expire_time = 0 + self._refresh_token_expire_time = 0 + + self._mail_user = '' + self._mail_port = 0 + self._mail_host = '' + self._mail_transceiver = '' + self._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.to_dict(), + '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, + } diff --git a/src/bot_api/model/version_dto.py b/src/bot_api/model/version_dto.py new file mode 100644 index 00000000..8ef98dc4 --- /dev/null +++ b/src/bot_api/model/version_dto.py @@ -0,0 +1,27 @@ +import traceback + +from cpl_core.console import Console + +from bot_api.abc.dto_abc import DtoABC + + +class VersionDTO(DtoABC): + + def __init__(self, major: str = None, minor: str = None, micro: str = None): + DtoABC.__init__(self) + + self._major = major + self._minor = minor + self._micro = micro + + def from_dict(self, values: dict): + self._major = values['Major'] + self._minor = values['Minor'] + self._micro = values['Micro'] + + def to_dict(self) -> dict: + return { + 'Major': self._major, + 'Minor': self._minor, + 'Micro': self._micro, + } diff --git a/src/bot_api/route/__init__.py b/src/bot_api/route/__init__.py index e69de29b..3f08538e 100644 --- a/src/bot_api/route/__init__.py +++ b/src/bot_api/route/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +bot Keksdose bot +~~~~~~~~~~~~~~~~~~~ + +Discord bot for the Keksdose discord Server + +:copyright: (c) 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'bot_api.route' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2022 sh-edraft.de' +__version__ = '0.2.3' + +from collections import namedtuple + + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='0', minor='2', micro='3')