diff --git a/publish_templates/*_template.txt b/publish_templates/all_template.txt similarity index 100% rename from publish_templates/*_template.txt rename to publish_templates/all_template.txt diff --git a/src/sh_edraft/source_code/__init__.py b/src/sh_edraft/coding/__init__.py similarity index 87% rename from src/sh_edraft/source_code/__init__.py rename to src/sh_edraft/coding/__init__.py index 1df505f4..375dc28f 100644 --- a/src/sh_edraft/source_code/__init__.py +++ b/src/sh_edraft/coding/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.source_code +sh_edraft.coding ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.source_code """ -__title__ = 'sh_edraft.source_code' +__title__ = 'sh_edraft.coding' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/source_code/model/__init__.py b/src/sh_edraft/coding/model/__init__.py similarity index 87% rename from src/sh_edraft/source_code/model/__init__.py rename to src/sh_edraft/coding/model/__init__.py index 5e7c6981..32344b00 100644 --- a/src/sh_edraft/source_code/model/__init__.py +++ b/src/sh_edraft/coding/model/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.source_code.model +sh_edraft.coding.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.source_code.model """ -__title__ = 'sh_edraft.source_code.model' +__title__ = 'sh_edraft.coding.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/source_code/model/version.py b/src/sh_edraft/coding/model/version.py similarity index 87% rename from src/sh_edraft/source_code/model/version.py rename to src/sh_edraft/coding/model/version.py index a7ba870e..26e4f9c0 100644 --- a/src/sh_edraft/source_code/model/version.py +++ b/src/sh_edraft/coding/model/version.py @@ -1,7 +1,7 @@ from typing import Optional -from sh_edraft.source_code.model.version_enum import VersionEnum -from sh_edraft.configuration.model.configuration_model_base import ConfigurationModelBase +from sh_edraft.coding.model.version_enum import VersionEnum +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase class Version(ConfigurationModelBase): diff --git a/src/sh_edraft/source_code/model/version_enum.py b/src/sh_edraft/coding/model/version_enum.py similarity index 100% rename from src/sh_edraft/source_code/model/version_enum.py rename to src/sh_edraft/coding/model/version_enum.py diff --git a/src/sh_edraft/configuration/__init__.py b/src/sh_edraft/configuration/__init__.py index 12f35645..10389a5b 100644 --- a/src/sh_edraft/configuration/__init__.py +++ b/src/sh_edraft/configuration/__init__.py @@ -20,7 +20,6 @@ __version__ = '2020.12.5' from collections import namedtuple # imports: -from .application_host import ApplicationHost VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=5) diff --git a/src/sh_edraft/configuration/model/__init__.py b/src/sh_edraft/configuration/base/__init__.py similarity index 86% rename from src/sh_edraft/configuration/model/__init__.py rename to src/sh_edraft/configuration/base/__init__.py index e5226338..b6b73bcd 100644 --- a/src/sh_edraft/configuration/model/__init__.py +++ b/src/sh_edraft/configuration/base/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.configuration.model +sh_edraft.configuration.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.configuration.model """ -__title__ = 'sh_edraft.configuration.model' +__title__ = 'sh_edraft.configuration.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/configuration/base/configuration_base.py b/src/sh_edraft/configuration/base/configuration_base.py new file mode 100644 index 00000000..4db03091 --- /dev/null +++ b/src/sh_edraft/configuration/base/configuration_base.py @@ -0,0 +1,23 @@ +from abc import abstractmethod +from collections import Callable + +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase +from sh_edraft.service.base.service_base import ServiceBase + + +class ConfigurationBase(ServiceBase): + + @abstractmethod + def __init__(self): + ServiceBase.__init__(self) + self._config: dict[type, object] = {} + + @property + @abstractmethod + def config(self) -> dict[type, object]: pass + + @abstractmethod + def add_config_by_type(self, key_type: type, value: object): pass + + @abstractmethod + def get_config_by_type(self, search_type: ConfigurationModelBase) -> Callable[ConfigurationModelBase]: pass diff --git a/src/sh_edraft/configuration/model/configuration_model_base.py b/src/sh_edraft/configuration/base/configuration_model_base.py similarity index 100% rename from src/sh_edraft/configuration/model/configuration_model_base.py rename to src/sh_edraft/configuration/base/configuration_model_base.py diff --git a/src/sh_edraft/configuration/configuration.py b/src/sh_edraft/configuration/configuration.py new file mode 100644 index 00000000..67140807 --- /dev/null +++ b/src/sh_edraft/configuration/configuration.py @@ -0,0 +1,27 @@ +from collections import Callable + +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase +from sh_edraft.configuration.base.configuration_base import ConfigurationBase + + +class Configuration(ConfigurationBase): + + def __init__(self): + super().__init__() + + @property + def config(self): + return self._config + + def create(self): pass + + def add_config_by_type(self, key_type: type, value: object): + self._config[key_type] = value + + def get_config_by_type(self, search_type: type) -> Callable[ConfigurationModelBase]: + if search_type not in self._config: + raise Exception(f'Config model by type {search_type} not found') + + for config_model in self._config: + if config_model == search_type: + return self._config[config_model] diff --git a/src/sh_edraft/hosting/__init__.py b/src/sh_edraft/hosting/__init__.py new file mode 100644 index 00000000..ceeb2b0e --- /dev/null +++ b/src/sh_edraft/hosting/__init__.py @@ -0,0 +1,3 @@ +# imports: + +from .application_host import ApplicationHost diff --git a/src/sh_edraft/configuration/application_host.py b/src/sh_edraft/hosting/application_host.py similarity index 66% rename from src/sh_edraft/configuration/application_host.py rename to src/sh_edraft/hosting/application_host.py index 770d9b81..f9b8fbf9 100644 --- a/src/sh_edraft/configuration/application_host.py +++ b/src/sh_edraft/hosting/application_host.py @@ -1,14 +1,16 @@ from datetime import datetime -from sh_edraft.service import ServiceProvider +from sh_edraft.hosting.base.application_host_base import ApplicationHostBase +from sh_edraft.service.service_provider import ServiceProvider -class ApplicationHost: +class ApplicationHost(ApplicationHostBase): def __init__(self): + ApplicationHostBase.__init__(self) self._services = ServiceProvider() - self._end_time: datetime = datetime.now() self._start_time: datetime = datetime.now() + self._end_time: datetime = datetime.now() @property def services(self): @@ -19,7 +21,7 @@ class ApplicationHost: return self._end_time @end_time.setter - def end_time(self, end_time: datetime) -> None: + def end_time(self, end_time: datetime): self._end_time = end_time @property @@ -27,7 +29,7 @@ class ApplicationHost: return self._start_time @start_time.setter - def start_time(self, start_time: datetime) -> None: + def start_time(self, start_time: datetime): self._start_time = start_time @property diff --git a/src/sh_edraft/hosting/base/__init__.py b/src/sh_edraft/hosting/base/__init__.py new file mode 100644 index 00000000..96c21b77 --- /dev/null +++ b/src/sh_edraft/hosting/base/__init__.py @@ -0,0 +1,2 @@ +# imports: +from .application_host_base import ApplicationHostBase diff --git a/src/sh_edraft/hosting/base/application_host_base.py b/src/sh_edraft/hosting/base/application_host_base.py new file mode 100644 index 00000000..20dbd9a5 --- /dev/null +++ b/src/sh_edraft/hosting/base/application_host_base.py @@ -0,0 +1,22 @@ +from abc import ABC, abstractmethod +from datetime import datetime + + +class ApplicationHostBase(ABC): + + @abstractmethod + def __init__(self): pass + + @property + @abstractmethod + def start_time(self) -> datetime: pass + + @start_time.setter + def start_time(self, start_time: datetime): pass + + @property + @abstractmethod + def end_time(self): pass + + @end_time.setter + def end_time(self, end_time: datetime): pass diff --git a/src/sh_edraft/hosting/model/__init__.py b/src/sh_edraft/hosting/model/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/sh_edraft/logging/base/logger_base.py b/src/sh_edraft/logging/base/logger_base.py index d9579484..47949898 100644 --- a/src/sh_edraft/logging/base/logger_base.py +++ b/src/sh_edraft/logging/base/logger_base.py @@ -1,14 +1,20 @@ from abc import abstractmethod -from sh_edraft.service.base import ServiceBase +from sh_edraft.hosting.application_host import ApplicationHost +from sh_edraft.logging.model.logging_settings import LoggingSettings +from sh_edraft.service.base.service_base import ServiceBase +from sh_edraft.time.model.time_format_settings import TimeFormatSettings class LoggerBase(ServiceBase): @abstractmethod - def __init__(self): + def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings): ServiceBase.__init__(self) + self._log_settings: LoggingSettings = logging_settings + self._time_format_settings: TimeFormatSettings = time_format + @abstractmethod def header(self, string: str): pass diff --git a/src/sh_edraft/logging/logger.py b/src/sh_edraft/logging/logger.py index 132369d8..f7a0a361 100644 --- a/src/sh_edraft/logging/logger.py +++ b/src/sh_edraft/logging/logger.py @@ -1,35 +1,23 @@ import datetime import os import traceback +from collections import Callable from string import Template -from typing import Optional -from sh_edraft.configuration.application_host import ApplicationHost +from sh_edraft.hosting.application_host import ApplicationHost from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.logging.model.log_level import LoggingLevel -from sh_edraft.logging.model.log_settings import LoggingSettings -from sh_edraft.time.model.time_format_settings import TimeFormatSettings +from sh_edraft.logging.model import LoggingSettings +from sh_edraft.logging.model.logging_level import LoggingLevel +from sh_edraft.time.model import TimeFormatSettings from sh_edraft.utils.console import Console class Logger(LoggerBase): - def __init__(self): - LoggerBase.__init__(self) + def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_host: ApplicationHost): + LoggerBase.__init__(self, logging_settings, time_format) - self._log_settings: Optional[LoggingSettings] = None - self._time_format_settings: Optional[TimeFormatSettings] = None - self._app_host: Optional[ApplicationHost] = None - - self._log: Optional[str] = None - self._path: Optional[str] = None - self._level: Optional[LoggingLevel] = None - self._console: Optional[LoggingLevel] = None - - def init(self, args: tuple): - self._log_settings = args[0] - self._time_format_settings = args[1] - self._app_host = args[2] + self._app_host: ApplicationHost = app_host self._log = Template(self._log_settings.filename).substitute( date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), diff --git a/src/sh_edraft/logging/model/__init__.py b/src/sh_edraft/logging/model/__init__.py index 6b232b0c..6712752d 100644 --- a/src/sh_edraft/logging/model/__init__.py +++ b/src/sh_edraft/logging/model/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.logging.model +sh_edraft.logging.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.logging.model """ -__title__ = 'sh_edraft.logging.model' +__title__ = 'sh_edraft.logging.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' @@ -20,8 +20,8 @@ __version__ = '2020.12.5' from collections import namedtuple # imports: -from .log_level import LoggingLevel -from .log_settings import LoggingSettings +from .logging_level import LoggingLevel +from .logging_settings import LoggingSettings VersionInfo = namedtuple('VersionInfo', 'major minor micro') version_info = VersionInfo(major=2020, minor=12, micro=5) diff --git a/src/sh_edraft/logging/model/log_level.py b/src/sh_edraft/logging/model/logging_level.py similarity index 100% rename from src/sh_edraft/logging/model/log_level.py rename to src/sh_edraft/logging/model/logging_level.py diff --git a/src/sh_edraft/logging/model/log_settings.py b/src/sh_edraft/logging/model/logging_settings.py similarity index 88% rename from src/sh_edraft/logging/model/log_settings.py rename to src/sh_edraft/logging/model/logging_settings.py index 1de23396..c5d1d77e 100644 --- a/src/sh_edraft/logging/model/log_settings.py +++ b/src/sh_edraft/logging/model/logging_settings.py @@ -1,10 +1,10 @@ import traceback from typing import Optional -from sh_edraft.configuration.model.configuration_model_base import ConfigurationModelBase -from sh_edraft.logging.model.log_settings_name import LogSettingsName +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase +from sh_edraft.logging.model.logging_settings_name import LogSettingsName from sh_edraft.utils.console import Console -from sh_edraft.logging.model.log_level import LoggingLevel +from sh_edraft.logging.model.logging_level import LoggingLevel class LoggingSettings(ConfigurationModelBase): diff --git a/src/sh_edraft/logging/model/log_settings_name.py b/src/sh_edraft/logging/model/logging_settings_name.py similarity index 100% rename from src/sh_edraft/logging/model/log_settings_name.py rename to src/sh_edraft/logging/model/logging_settings_name.py diff --git a/src/sh_edraft/messenger/__init__.py b/src/sh_edraft/messaging/__init__.py similarity index 88% rename from src/sh_edraft/messenger/__init__.py rename to src/sh_edraft/messaging/__init__.py index 8d501a96..db61154c 100644 --- a/src/sh_edraft/messenger/__init__.py +++ b/src/sh_edraft/messaging/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.messenger +sh_edraft.messaging ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.messenger """ -__title__ = 'sh_edraft.messenger' +__title__ = 'sh_edraft.messaging' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/publish/base/publisher_base.py b/src/sh_edraft/publish/base/publisher_base.py deleted file mode 100644 index 51c3d086..00000000 --- a/src/sh_edraft/publish/base/publisher_base.py +++ /dev/null @@ -1,21 +0,0 @@ -from abc import abstractmethod - -from sh_edraft.service.base import ServiceBase - - -class PublisherBase(ServiceBase): - - @abstractmethod - def __init__(self): - ServiceBase.__init__(self) - - @property - @abstractmethod - def source_path(self) -> str: pass - - @property - @abstractmethod - def dist_path(self) -> str: pass - - @abstractmethod - def publish(self) -> str: pass diff --git a/src/sh_edraft/publish/__init__.py b/src/sh_edraft/publishing/__init__.py similarity index 89% rename from src/sh_edraft/publish/__init__.py rename to src/sh_edraft/publishing/__init__.py index 7b162462..3147018a 100644 --- a/src/sh_edraft/publish/__init__.py +++ b/src/sh_edraft/publishing/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.publish +sh_edraft.publishing ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.publish """ -__title__ = 'sh_edraft.publish' +__title__ = 'sh_edraft.publishing' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/publish/base/__init__.py b/src/sh_edraft/publishing/base/__init__.py similarity index 87% rename from src/sh_edraft/publish/base/__init__.py rename to src/sh_edraft/publishing/base/__init__.py index a7e178d1..041cfa8f 100644 --- a/src/sh_edraft/publish/base/__init__.py +++ b/src/sh_edraft/publishing/base/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.publish.base +sh_edraft.publishing.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.publish.base """ -__title__ = 'sh_edraft.publish.base' +__title__ = 'sh_edraft.publishing.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/publishing/base/publisher_base.py b/src/sh_edraft/publishing/base/publisher_base.py new file mode 100644 index 00000000..f2038018 --- /dev/null +++ b/src/sh_edraft/publishing/base/publisher_base.py @@ -0,0 +1,32 @@ +from abc import abstractmethod + +from sh_edraft.logging.base.logger_base import LoggerBase +from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel +from sh_edraft.service.base.service_base import ServiceBase + + +class PublisherBase(ServiceBase): + + @abstractmethod + def __init__(self, logger: LoggerBase, publish_settings: PublishSettingsModel): + ServiceBase.__init__(self) + + self._logger: LoggerBase = logger + self._publish_settings: PublishSettingsModel = publish_settings + + @property + @abstractmethod + def source_path(self) -> str: pass + + @property + @abstractmethod + def dist_path(self) -> str: pass + + @abstractmethod + def include(self, path: str): pass + + @abstractmethod + def exclude(self, path: str): pass + + @abstractmethod + def publish(self) -> str: pass diff --git a/src/sh_edraft/publish/model/__init__.py b/src/sh_edraft/publishing/model/__init__.py similarity index 88% rename from src/sh_edraft/publish/model/__init__.py rename to src/sh_edraft/publishing/model/__init__.py index dbc1c3b5..91e2bd18 100644 --- a/src/sh_edraft/publish/model/__init__.py +++ b/src/sh_edraft/publishing/model/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.publish.model +sh_edraft.publishing.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.publish.model """ -__title__ = 'sh_edraft.publish.model' +__title__ = 'sh_edraft.publishing.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/publishing/model/publish_settings_model.py b/src/sh_edraft/publishing/model/publish_settings_model.py new file mode 100644 index 00000000..898d01d9 --- /dev/null +++ b/src/sh_edraft/publishing/model/publish_settings_model.py @@ -0,0 +1,83 @@ +import traceback +from typing import Optional + +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase +from sh_edraft.publishing.model import Template +from sh_edraft.publishing.model.publish_settings_name import PublishSettingsName +from sh_edraft.utils import Console + + +class PublishSettingsModel(ConfigurationModelBase): + + def __init__(self): + ConfigurationModelBase.__init__(self) + + self._source_path: Optional[str] = None + self._dist_path: Optional[str] = None + self._templates: Optional[list[Template]] = None + + self._included_files: Optional[list[str]] = None + self._excluded_files: Optional[list[str]] = None + + self._template_ending: Optional[str] = None + + @property + def source_path(self) -> str: + return self._source_path + + @source_path.setter + def source_path(self, source_path: str): + self._source_path = source_path + + @property + def dist_path(self) -> str: + return self._dist_path + + @dist_path.setter + def dist_path(self, dist_path: str): + self._dist_path = dist_path + + @property + def templates(self) -> list[Template]: + return self._templates + + @templates.setter + def templates(self, templates: list[Template]): + self._templates = templates + + @property + def included_files(self) -> list[str]: + return self._included_files + + @included_files.setter + def included_files(self, included_files: list[str]): + self._included_files = included_files + + @property + def excluded_files(self) -> list[str]: + return self._excluded_files + + @excluded_files.setter + def excluded_files(self, excluded_files: list[str]): + self._excluded_files = excluded_files + + @property + def template_ending(self) -> str: + return self._template_ending + + @template_ending.setter + def template_ending(self, template_ending: str): + self._template_ending = template_ending + + def from_dict(self, settings: dict): + try: + self._source_path = settings[PublishSettingsName.source_path.value] + self._dist_path = settings[PublishSettingsName.dist_path.value] + self._templates = settings[PublishSettingsName.templates.value] + self._included_files = settings[PublishSettingsName.included_files.value] + self._excluded_files = settings[PublishSettingsName.excluded_files.value] + self._template_ending = settings[PublishSettingsName.template_ending.value] + except Exception as e: + Console.write_line( + f'[ ERROR ] [ {__name__} ]: Reading error in {PublishSettingsName.publish.value} settings', 'red') + Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}', 'red') diff --git a/src/sh_edraft/publishing/model/publish_settings_name.py b/src/sh_edraft/publishing/model/publish_settings_name.py new file mode 100644 index 00000000..80033c68 --- /dev/null +++ b/src/sh_edraft/publishing/model/publish_settings_name.py @@ -0,0 +1,12 @@ +from enum import Enum + + +class PublishSettingsName(Enum): + + publish = 'Publish' + source_path = 'SourcePath' + dist_path = 'DistPath' + templates = 'Templates' + included_files = 'IncludedFiles' + excluded_files = 'ExcludedFiles' + template_ending = 'TemplateEnding' diff --git a/src/sh_edraft/publish/model/template.py b/src/sh_edraft/publishing/model/template.py similarity index 95% rename from src/sh_edraft/publish/model/template.py rename to src/sh_edraft/publishing/model/template.py index d917374b..922a5df5 100644 --- a/src/sh_edraft/publish/model/template.py +++ b/src/sh_edraft/publishing/model/template.py @@ -1,8 +1,8 @@ from typing import Optional -from sh_edraft.source_code.model.version import Version -from sh_edraft.configuration.model import ConfigurationModelBase -from sh_edraft.publish.model.template_enum import TemplateEnum +from sh_edraft.coding.model.version import Version +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase +from sh_edraft.publishing.model.template_enum import TemplateEnum class Template(ConfigurationModelBase): diff --git a/src/sh_edraft/publish/model/template_enum.py b/src/sh_edraft/publishing/model/template_enum.py similarity index 100% rename from src/sh_edraft/publish/model/template_enum.py rename to src/sh_edraft/publishing/model/template_enum.py diff --git a/src/sh_edraft/publish/publisher.py b/src/sh_edraft/publishing/publisher.py similarity index 79% rename from src/sh_edraft/publish/publisher.py rename to src/sh_edraft/publishing/publisher.py index 7fae4fff..1e7f55e6 100644 --- a/src/sh_edraft/publish/publisher.py +++ b/src/sh_edraft/publishing/publisher.py @@ -1,35 +1,25 @@ import os import shutil from string import Template as stringTemplate -from typing import Optional from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.publish.base.publisher_base import PublisherBase -from sh_edraft.publish.model.template import Template +from sh_edraft.publishing.base.publisher_base import PublisherBase +from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel +from sh_edraft.publishing.model.template import Template class Publisher(PublisherBase): - def __init__(self): - super().__init__() - - self._logger: Optional[LoggerBase] = None - self._source_path: Optional[str] = None - self._dist_path: Optional[str] = None - self._settings: Optional[list[Template]] = None - - self._included_files: list[str] = [] - self._excluded_files: list[str] = [] - - self._template_ending = '_template.txt' + def __init__(self, logger: LoggerBase, publish_settings: PublishSettingsModel): + super().__init__(logger, publish_settings) @property def source_path(self) -> str: - return self._source_path + return self._publish_settings.source_path @property def dist_path(self): - return self._dist_path + return self._publish_settings.dist_path def _get_template_output(self, t: Template, name: str, imports: str) -> str: self._logger.trace(__name__, f'Started {__name__}._get_template_output') @@ -60,41 +50,41 @@ class Publisher(PublisherBase): def _read_source_path(self): self._logger.trace(__name__, f'Started {__name__}._read_source_path') - for r, d, f in os.walk(self._source_path): + for r, d, f in os.walk(self._publish_settings.source_path): for file in f: - if file.endswith('.py') or file in self._included_files: - self._included_files.append(os.path.join(r, file)) + if file.endswith('.py') or file in self._publish_settings.included_files: + self._publish_settings.included_files.append(os.path.join(r, file)) self._logger.trace(__name__, f'Stopped {__name__}._read_source_path') def _read_templates(self): self._logger.trace(__name__, f'Started {__name__}._read_templates') - for t in self._settings: + for t in self._publish_settings.templates: output_template: str = '' if not os.path.isfile(t.template_path): - raise Exception(f'Template not found: {t.template_path}') + self._logger.fatal(__name__, f'Template not found: {t.template_path}') with open(t.template_path) as template: t.file_content = template.read() template.close() if t.file_content == '': - raise Exception(f'Template is empty: {t.template_path}') + self._logger.fatal(__name__, f'Template is empty: {t.template_path}') self._logger.trace(__name__, f'Stopped {__name__}._read_templates') def _create_dist_path(self): self._logger.trace(__name__, f'Started {__name__}._create_dist_path') - if os.path.isdir(self._dist_path): + if os.path.isdir(self._publish_settings.dist_path): try: - shutil.rmtree(self._dist_path) - self._logger.info(__name__, f'Deleted {self._dist_path}') + shutil.rmtree(self._publish_settings.dist_path) + self._logger.info(__name__, f'Deleted {self._publish_settings.dist_path}') except Exception as e: self._logger.fatal(__name__, f'Cannot delete old dist directory', e) - if not os.path.isdir(self._dist_path): + if not os.path.isdir(self._publish_settings.dist_path): try: - os.makedirs(self._dist_path) - self._logger.debug(__name__, f'Created directories: {self._dist_path}') + os.makedirs(self._publish_settings.dist_path) + self._logger.debug(__name__, f'Created directories: {self._publish_settings.dist_path}') self._logger.info(__name__, f'Created dist directory') except Exception as e: self._logger.fatal(__name__, f'Cannot create dist directory', e) @@ -115,11 +105,11 @@ class Publisher(PublisherBase): def _write_templates(self): self._logger.trace(__name__, f'Started {__name__}._write_templates') - for template in self._settings: - for file in self._included_files: - if os.path.basename(file) == '__init__.py' and file not in self._excluded_files: + for template in self._publish_settings.templates: + for file in self._publish_settings.included_files: + if os.path.basename(file) == '__init__.py' and file not in self._publish_settings.excluded_files: template_name = template.name - if template.name == '*' or template.name == '': + if template.name == 'all' or template.name == '': template_name = self._get_template_name_from_dirs(file) else: name = self._get_template_name_from_dirs(file) @@ -170,16 +160,16 @@ class Publisher(PublisherBase): def _copy_all_included_files(self): self._logger.trace(__name__, f'Started {__name__}._copy_all_included_files') - dist_path = self._dist_path - if self._dist_path.endswith('/'): + dist_path = self._publish_settings.dist_path + if self._publish_settings.dist_path.endswith('/'): dist_path = dist_path[:len(dist_path) - 1] - for file in self._included_files: + for file in self._publish_settings.included_files: is_file_excluded = False - if file in self._excluded_files: + if file in self._publish_settings.excluded_files: is_file_excluded = True else: - for excluded in self._excluded_files: + for excluded in self._publish_settings.excluded_files: if file.__contains__(excluded): is_file_excluded = True @@ -212,26 +202,18 @@ class Publisher(PublisherBase): def include(self, path: str): self._logger.trace(__name__, f'Started {__name__}.include') - self._included_files.append(path) + self._publish_settings.included_files.append(path) self._logger.trace(__name__, f'Stopped {__name__}.include') def exclude(self, path: str): self._logger.trace(__name__, f'Started {__name__}.exclude') - self._excluded_files.append(path) + self._publish_settings.excluded_files.append(path) self._logger.trace(__name__, f'Stopped {__name__}.exclude') - def init(self, args: tuple): - self._logger: LoggerBase = args[0] - self._source_path: str = args[1] - self._dist_path: str = args[2] - self._settings: list[Template] = args[3] - - self._logger.header(f'{__name__}:') - def create(self): self._logger.trace(__name__, f'Started {__name__}.create') - if not self._dist_path.endswith('/'): - self._dist_path += '/' + if not self._publish_settings.dist_path.endswith('/'): + self._publish_settings.dist_path += '/' self._read_source_path() self._read_templates() diff --git a/src/sh_edraft/service/base/service_base.py b/src/sh_edraft/service/base/service_base.py index 2e4a4934..e135c2a9 100644 --- a/src/sh_edraft/service/base/service_base.py +++ b/src/sh_edraft/service/base/service_base.py @@ -6,8 +6,5 @@ class ServiceBase(ABC): @abstractmethod def __init__(self): pass - @abstractmethod - def init(self, args: tuple): pass - @abstractmethod def create(self): pass diff --git a/src/sh_edraft/service/base/service_provider_base.py b/src/sh_edraft/service/base/service_provider_base.py index ee1f319a..9deb0918 100644 --- a/src/sh_edraft/service/base/service_provider_base.py +++ b/src/sh_edraft/service/base/service_provider_base.py @@ -3,7 +3,6 @@ from collections import Callable from typing import Type from sh_edraft.service.base.service_base import ServiceBase -from sh_edraft.service.model.provide_state import ProvideState class ServiceProviderBase(ServiceBase): @@ -11,18 +10,23 @@ class ServiceProviderBase(ServiceBase): @abstractmethod def __init__(self): ServiceBase.__init__(self) - self._transient_services: list[ProvideState] = [] - self._scoped_services: list[ProvideState] = [] - self._singleton_services: list[ServiceBase] = [] + + self._transient_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} + self._scoped_services: dict[Type[ServiceBase], Type[ServiceBase]] = {} + self._singleton_services: dict[Type[ServiceBase], ServiceBase] = {} + + @property + @abstractmethod + def config(self): pass @abstractmethod - def add_transient(self, service: Type[ServiceBase], *args): pass + def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): pass @abstractmethod - def add_scoped(self, service: Type[ServiceBase], *args): pass + def add_scoped(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): pass @abstractmethod - def add_singleton(self, service: Type[ServiceBase], *args): pass + def add_singleton(self, service_type: Type[ServiceBase], service: ServiceBase): pass @abstractmethod def get_service(self, instance_type: Type[ServiceBase]) -> Callable[ServiceBase]: pass diff --git a/src/sh_edraft/service/model/__init__.py b/src/sh_edraft/service/model/__init__.py index 9a4effc3..96c24ada 100644 --- a/src/sh_edraft/service/model/__init__.py +++ b/src/sh_edraft/service/model/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.service.model +sh_edraft.service.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.service.model """ -__title__ = 'sh_edraft.service.model' +__title__ = 'sh_edraft.service.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/service/service_provider.py b/src/sh_edraft/service/service_provider.py index fdc93c36..66cb567e 100644 --- a/src/sh_edraft/service/service_provider.py +++ b/src/sh_edraft/service/service_provider.py @@ -1,69 +1,83 @@ from collections import Callable +from inspect import signature, Parameter from typing import Type -from termcolor import colored - +from sh_edraft.configuration.configuration import Configuration +from sh_edraft.hosting.base.application_host_base import ApplicationHostBase +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase from sh_edraft.service.base.service_provider_base import ServiceProviderBase from sh_edraft.service.base.service_base import ServiceBase -from sh_edraft.service.model.provide_state import ProvideState class ServiceProvider(ServiceProviderBase): def __init__(self): super().__init__() + self._config = Configuration() - def init(self, args: tuple): pass + @property + def config(self): + return self._config def create(self): pass - @staticmethod - def _create_instance(service: type[ServiceBase], args: tuple) -> ServiceBase: - instance = service() - try: - instance.init(args) - return instance - except Exception as e: - print(colored(f'Argument error\n{e}', 'red')) + def _create_instance(self, service: Callable[ServiceBase]) -> ServiceBase: + sig = signature(service.__init__) + params = [] + for param in sig.parameters.items(): + parameter = param[1] + if parameter.name != 'self' and parameter.annotation != Parameter.empty: + if issubclass(parameter.annotation, ServiceBase): + params.append(self.get_service(parameter.annotation)) - def add_transient(self, service: Type[ServiceBase], *args): - self._transient_services.append(ProvideState(service, args)) + elif issubclass(parameter.annotation, ConfigurationModelBase) or issubclass(parameter.annotation, ApplicationHostBase): + params.append(self._config.get_config_by_type(parameter.annotation)) - def add_scoped(self, service: Type[ServiceBase], *args): - self._transient_services.append(ProvideState(service, args)) + return service(*params) + # try: + # instance.init(args) + # return instance + # except Exception as e: + # print(colored(f'Argument error\n{e}', 'red')) - def add_singleton(self, service: Type[ServiceBase], *args): + def add_transient(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): + self._transient_services[service_type] = service + + def add_scoped(self, service_type: Type[ServiceBase], service: Type[ServiceBase]): + self._scoped_services[service_type] = service + + def add_singleton(self, service_type: Type[ServiceBase], service: ServiceBase): for known_service in self._singleton_services: - if type(known_service) == type(service): - raise Exception(f'Service from type {type(service)} already exists') + if type(known_service) == type(service_type): + raise Exception(f'Service with type {type(service_type)} already exists') - self._singleton_services.append(self._create_instance(service, args)) + self._singleton_services[service_type] = self._create_instance(service) def get_service(self, instance_type: Type[ServiceBase]) -> Callable[ServiceBase]: - for state in self._transient_services: - if isinstance(state.service, type(instance_type)): - return self._create_instance(state.service, state.args) + for service in self._transient_services: + if service == instance_type and isinstance(self._transient_services[service], type(instance_type)): + return self._create_instance(self._transient_services[service]) - for state in self._scoped_services: - if isinstance(state.service, type(instance_type)): - return self._create_instance(state.service, state.args) + for service in self._scoped_services: + if service == instance_type and isinstance(self._scoped_services[service], type(instance_type)): + return self._create_instance(self._scoped_services[service]) for service in self._singleton_services: - if isinstance(service, instance_type): - return service + if service == instance_type and isinstance(self._singleton_services[service], instance_type): + return self._singleton_services[service] - def remove_service(self, instance_type: type): - for state in self._transient_services: - if isinstance(state.service, type(instance_type)): - self._transient_services.remove(state) + def remove_service(self, instance_type: Type[ServiceBase]): + for service in self._transient_services: + if isinstance(service, type(instance_type)): + del self._transient_services[service] return - for state in self._scoped_services: - if isinstance(state.service, type(instance_type)): - self._scoped_services.remove(state) + for service in self._scoped_services: + if isinstance(service, type(instance_type)): + del self._scoped_services[service] return for service in self._singleton_services: if isinstance(service, instance_type): - self._singleton_services.remove(service) + del self._singleton_services[service] return diff --git a/src/sh_edraft/time/model/__init__.py b/src/sh_edraft/time/model/__init__.py index e786e832..6686c3d3 100644 --- a/src/sh_edraft/time/model/__init__.py +++ b/src/sh_edraft/time/model/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -sh_edraft.time.model +sh_edraft.time.base ~~~~~~~~~~~~~~~~~~~ @@ -11,7 +11,7 @@ sh_edraft.time.model """ -__title__ = 'sh_edraft.time.model' +__title__ = 'sh_edraft.time.base' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 sh-edraft.de' diff --git a/src/sh_edraft/time/model/time_format_settings.py b/src/sh_edraft/time/model/time_format_settings.py index 9c6b33ce..f092e27b 100644 --- a/src/sh_edraft/time/model/time_format_settings.py +++ b/src/sh_edraft/time/model/time_format_settings.py @@ -1,7 +1,7 @@ import traceback from typing import Optional -from sh_edraft.configuration.model import ConfigurationModelBase +from sh_edraft.configuration.base.configuration_model_base import ConfigurationModelBase from sh_edraft.time.model.time_format_settings_names import TimeFormatSettingsNames from sh_edraft.utils.console import Console diff --git a/src/tests/logger.py b/src/tests/logger.py deleted file mode 100644 index 47b5e3ab..00000000 --- a/src/tests/logger.py +++ /dev/null @@ -1,50 +0,0 @@ -import os -from string import Template - -from sh_edraft.configuration import ApplicationHost -from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.logging.logger import Logger -from sh_edraft.logging.model.log_settings import LoggingSettings -from sh_edraft.time.model.time_format_settings import TimeFormatSettings - - -class LoggerTest: - - @staticmethod - def start(app_host: ApplicationHost): - services = app_host.services - - log_settings = LoggingSettings() - log_settings.from_dict({ - "Path": "logs/", - "Filename": "log_$start_time.log", - "ConsoleLogLevel": "TRACE", - "FileLogLevel": "TRACE" - }) - - time_format_settings = TimeFormatSettings() - time_format_settings.from_dict({ - "DateFormat": "%Y-%m-%d", - "TimeFormat": "%H:%M:%S", - "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", - "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" - }) - - services.add_singleton(Logger, log_settings, time_format_settings, app_host) - logger: Logger = services.get_service(LoggerBase) - - if logger is None: - raise Exception(f'{__name__}: Service is None') - - logger.create() - logger.info(__name__, 'test') - - if not os.path.isdir(log_settings.path): - raise Exception(f'{__name__}: Log path was not created') - - log_file = Template(log_settings.filename).substitute( - date_time_now=app_host.date_time_now.strftime(time_format_settings.date_time_format), - start_time=app_host.start_time.strftime(time_format_settings.date_time_log_format) - ) - if not os.path.isfile(log_settings.path + log_file): - raise Exception(f'{__name__}: Log file was not created') diff --git a/src/tests/logging/__init__.py b/src/tests/logging/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/logging/logger.py b/src/tests/logging/logger.py new file mode 100644 index 00000000..37ea1346 --- /dev/null +++ b/src/tests/logging/logger.py @@ -0,0 +1,210 @@ +import os +import shutil +import unittest +from datetime import datetime +from string import Template + +from sh_edraft.hosting import ApplicationHost +from sh_edraft.logging import Logger +from sh_edraft.logging.model import LoggingSettings +from sh_edraft.time.model import TimeFormatSettings + + +class LoggerTest(unittest.TestCase): + + def setUp(self): + self._app_host = ApplicationHost() + self._services = self._app_host.services + self._services.create() + + self._log_settings = LoggingSettings() + self._log_settings.from_dict({ + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }) + + self._time_format_settings = TimeFormatSettings() + self._time_format_settings.from_dict({ + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }) + + def tearDown(self): + if os.path.isdir(self._log_settings.path): + shutil.rmtree(self._log_settings.path) + + def _check_general_requirements(self): + self.assertIsNotNone(self._services) + self.assertIsNotNone(self._log_settings) + self.assertIsNotNone(self._time_format_settings) + + def test_create(self): + print(f'{__name__}.test_create:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + self.assertTrue(os.path.isdir(self._log_settings.path)) + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + self.assertTrue(os.path.isfile(self._log_settings.path + log_file)) + + def test_header(self): + print(f'{__name__}.test_header:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + logger.header('HeaderTest:') + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + log_content = [] + + try: + with open(self._log_settings.path + log_file, "r") as log: + log_content = log.readlines() + log.close() + except Exception as e: + print('Cannot open log file', e) + + self.assertGreater(len(log_content), 0) + self.assertEqual(log_content[len(log_content) - 1], 'HeaderTest:\n') + + def test_trace(self): + print(f'{__name__}.test_trace:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + logger.trace(__name__, f'{__name__}.test_trace:') + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + log_content = [] + + try: + with open(self._log_settings.path + log_file, "r") as log: + log_content = log.readlines() + log.close() + except Exception as e: + print('Cannot open log file', e) + + self.assertGreater(len(log_content), 0) + self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ TRACE ] [ {__name__} ]: {__name__}.test_trace:\n')) + + def test_debug(self): + print(f'{__name__}.test_debug:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + logger.debug(__name__, f'{__name__}.test_debug:') + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + log_content = [] + + try: + with open(self._log_settings.path + log_file, "r") as log: + log_content = log.readlines() + log.close() + except Exception as e: + print('Cannot open log file', e) + + self.assertGreater(len(log_content), 0) + self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ DEBUG ] [ {__name__} ]: {__name__}.test_debug:\n')) + + def test_info(self): + print(f'{__name__}.test_info:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + logger.info(__name__, f'{__name__}.test_info:') + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + log_content = [] + + try: + with open(self._log_settings.path + log_file, "r") as log: + log_content = log.readlines() + log.close() + except Exception as e: + print('Cannot open log file', e) + + self.assertGreater(len(log_content), 0) + self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ INFO ] [ {__name__} ]: {__name__}.test_info:\n')) + + def test_warn(self): + print(f'{__name__}.test_warn:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + logger.warn(__name__, f'{__name__}.test_warn:') + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + log_content = [] + + try: + with open(self._log_settings.path + log_file, "r") as log: + log_content = log.readlines() + log.close() + except Exception as e: + print('Cannot open log file', e) + + self.assertGreater(len(log_content), 0) + self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ WARN ] [ {__name__} ]: {__name__}.test_warn:\n')) + + def test_error(self): + print(f'{__name__}.test_error:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + logger.error(__name__, f'{__name__}.test_error:') + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + log_content = [] + + try: + with open(self._log_settings.path + log_file, "r") as log: + log_content = log.readlines() + log.close() + except Exception as e: + print('Cannot open log file', e) + + self.assertGreater(len(log_content), 0) + self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ ERROR ] [ {__name__} ]: {__name__}.test_error:\n')) + + def test_fatal(self): + print(f'{__name__}.test_fatal:') + logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + logger.create() + with self.assertRaises(SystemExit): + logger.fatal(__name__, f'{__name__}.test_fatal:') + + log_file = Template(self._log_settings.filename).substitute( + date_time_now=self._app_host.date_time_now.strftime(self._time_format_settings.date_time_format), + start_time=self._app_host.start_time.strftime(self._time_format_settings.date_time_log_format) + ) + log_content = [] + + try: + with open(self._log_settings.path + log_file, "r") as log: + log_content = log.readlines() + log.close() + except Exception as e: + print('Cannot open log file', e) + + self.assertGreater(len(log_content), 0) + self.assertTrue(log_content[len(log_content) - 1].endswith(f'[ ERROR ] [ {__name__} ]: {__name__}.test_fatal:\n')) diff --git a/src/tests/publisher.py b/src/tests/publisher.py index 73923471..847d76b4 100644 --- a/src/tests/publisher.py +++ b/src/tests/publisher.py @@ -1,11 +1,11 @@ import os from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.publish.base import PublisherBase +from sh_edraft.publishing.base import PublisherBase from sh_edraft.service.base import ServiceProviderBase -from sh_edraft.source_code.model import Version -from sh_edraft.publish import Publisher -from sh_edraft.publish.model import Template +from sh_edraft.coding.model import Version +from sh_edraft.publishing import Publisher +from sh_edraft.publishing.model import Template class PublisherTest: diff --git a/src/tests/publishing/__init__.py b/src/tests/publishing/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/publishing/publisher.py b/src/tests/publishing/publisher.py new file mode 100644 index 00000000..ff64d0ae --- /dev/null +++ b/src/tests/publishing/publisher.py @@ -0,0 +1,95 @@ +import os +import shutil +import unittest + +from sh_edraft.hosting import ApplicationHost +from sh_edraft.logging import Logger +from sh_edraft.logging.base import LoggerBase +from sh_edraft.logging.model import LoggingSettings +from sh_edraft.publishing import Publisher +from sh_edraft.publishing.base import PublisherBase +from sh_edraft.publishing.model import Template +from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel +from sh_edraft.coding.model import Version +from sh_edraft.time.model import TimeFormatSettings + + +class PublisherTest(unittest.TestCase): + + def _config(self): + self._log_settings = LoggingSettings() + self._log_settings.from_dict({ + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }) + + self._time_format_settings = TimeFormatSettings() + self._time_format_settings.from_dict({ + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }) + + self._version = Version(2020, 12, 5).to_dict() + templates = [ + Template( + '../../publish_templates/all_template.txt', + 'all', + '', + '', + '2020', + 'sh-edraft.de', + 'MIT', + ', see LICENSE for more details.', + '', + 'Sven Heidemann', + self._version + ), + Template( + '../../publish_templates/all_template.txt', + 'sh_edraft', + 'common python library', + 'Library to share common classes and models used at sh-edraft.de', + '2020', + 'sh-edraft.de', + 'MIT', + ', see LICENSE for more details.', + '', + 'Sven Heidemann', + self._version + ) + ] + + self._source_path = '../' + self._dist_path = '../../dist' + + self._publish_settings_model = PublishSettingsModel() + self._publish_settings_model.from_dict({ + "SourcePath": self._source_path, + "DistPath": self._dist_path, + "Templates": templates, + "IncludedFiles": [], + "ExcludedFiles": [], + "TemplateEnding": "_template.txt", + }) + + def setUp(self): + self._config() + + self._app_host = ApplicationHost() + self._logger = Logger(self._log_settings, self._time_format_settings, self._app_host) + self._logger.create() + + def tearDown(self): + if os.path.isdir(self._log_settings.path): + shutil.rmtree(self._log_settings.path) + + def test_create(self): + publisher: Publisher = Publisher(self._logger, self._publish_settings_model) + self.assertIsNotNone(publisher) + + publisher.create() + self.assertTrue(os.path.isdir(self._dist_path)) diff --git a/src/tests/service_provider.py b/src/tests/service_provider.py deleted file mode 100644 index 676cc604..00000000 --- a/src/tests/service_provider.py +++ /dev/null @@ -1,20 +0,0 @@ -from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.publish import Publisher -from sh_edraft.publish.base import PublisherBase -from sh_edraft.service.base import ServiceProviderBase - - -class ServiceProviderTest: - - @staticmethod - def start(services: ServiceProviderBase): - services.add_transient(Publisher, services.get_service(LoggerBase), '../', '../../dist', []) - - publisher: Publisher = services.get_service(PublisherBase) - - if publisher is None or publisher.source_path != '../' or publisher.dist_path != '../../dist': - raise Exception(f'{__name__}: Invalid value in {Publisher.__name__}') - - services.remove_service(PublisherBase) - if services.get_service(PublisherBase) is not None: - raise Exception(f'{__name__}: Service {Publisher.__name__} was not removed') diff --git a/src/tests/service_providing/__init__.py b/src/tests/service_providing/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/service_providing/service_provider.py b/src/tests/service_providing/service_provider.py new file mode 100644 index 00000000..1c136976 --- /dev/null +++ b/src/tests/service_providing/service_provider.py @@ -0,0 +1,158 @@ +import unittest + +from sh_edraft.hosting import ApplicationHost +from sh_edraft.logging import Logger +from sh_edraft.logging.base import LoggerBase +from sh_edraft.logging.model import LoggingSettings +from sh_edraft.publishing import Publisher +from sh_edraft.publishing.base import PublisherBase +from sh_edraft.publishing.model.publish_settings_model import PublishSettingsModel +from sh_edraft.service import ServiceProvider +from sh_edraft.service.base import ServiceBase +from sh_edraft.time.model import TimeFormatSettings + + +class ServiceProviderTest(unittest.TestCase): + + def setUp(self): + self._app_host = ApplicationHost() + self._services = self._app_host.services + self._services.create() + + self._log_settings = LoggingSettings() + self._log_settings.from_dict({ + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }) + self._services.config.add_config_by_type(LoggingSettings, self._log_settings) + + self._time_format_settings = TimeFormatSettings() + self._time_format_settings.from_dict({ + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }) + self._services.config.add_config_by_type(TimeFormatSettings, self._time_format_settings) + self._services.config.add_config_by_type(ApplicationHost, self._app_host) + + self._publish_settings_model = PublishSettingsModel() + self._publish_settings_model.from_dict({ + "SourcePath": "../", + "DistPath": "../../dist", + "Templates": [], + "IncludedFiles": [], + "ExcludedFiles": [], + "TemplateEnding": "_template.txt", + }) + self._services.config.add_config_by_type(PublishSettingsModel, self._publish_settings_model) + + def _check_general_requirements(self): + self.assertIsNotNone(self._services) + + def _add_logger(self): + self._services.add_singleton(LoggerBase, Logger) + logger: Logger = self._services.get_service(LoggerBase) + logger.create() + + def test_create(self): + print(f'{__name__}.test_create:') + provider = ServiceProvider() + self.assertIsNotNone(provider) + provider.create() + self.assertIsNotNone(provider) + + def test_add_singleton(self): + print(f'{__name__}.test_add_singleton:') + self._check_general_requirements() + + self._services.add_singleton(LoggerBase, Logger) + self.assertGreater(len(self._services._singleton_services), 0) + + found = False + for service_type in self._services._singleton_services: + service = self._services._singleton_services[service_type] + if service_type == LoggerBase and ( + isinstance(service, Logger) and isinstance(service, LoggerBase) and isinstance(service, ServiceBase) + ): + if not found: + found = True + + self.assertTrue(found) + + found = False + for service_type in self._services._singleton_services: + service = self._services._singleton_services[service_type] + if service_type == PublisherBase and ( + isinstance(service, Publisher) and isinstance(service, PublisherBase) and isinstance(service, ServiceBase) + ): + if not found: + found = True + + self.assertFalse(found) + + def test_get_singleton(self): + print(f'{__name__}.test_get_singleton:') + self._check_general_requirements() + + self._services.add_singleton(LoggerBase, Logger) + logger: Logger = self._services.get_service(LoggerBase) + self.assertIsNotNone(logger) + self.assertTrue(isinstance(logger, Logger)) + self.assertTrue(isinstance(logger, LoggerBase)) + self.assertTrue(isinstance(logger, ServiceBase)) + + self.assertEqual(logger._log_settings, self._log_settings) + self.assertEqual(logger._time_format_settings, self._time_format_settings) + self.assertEqual(logger._app_host, self._app_host) + + def test_add_scoped(self): + print(f'{__name__}.test_add_scoped:') + self._check_general_requirements() + self._add_logger() + + self._services.add_scoped(PublisherBase, Publisher) + + def test_get_scoped(self): + print(f'{__name__}.test_get_scoped:') + self._check_general_requirements() + self._add_logger() + + self._services.add_scoped(PublisherBase, Publisher) + publisher: Publisher = self._services.get_service(PublisherBase) + self.assertIsNotNone(publisher) + self.assertTrue(isinstance(publisher, Publisher)) + self.assertTrue(isinstance(publisher, PublisherBase)) + self.assertTrue(isinstance(publisher, ServiceBase)) + + self.assertTrue(isinstance(publisher._logger, Logger)) + self.assertTrue(isinstance(publisher._logger, LoggerBase)) + self.assertTrue(isinstance(publisher._logger, ServiceBase)) + + def test_add_transient(self): + print(f'{__name__}.test_add_transient:') + self._check_general_requirements() + self._add_logger() + + self._services.add_transient(PublisherBase, Publisher) + self.assertGreater(len(self._services._transient_services), 0) + + self.assertTrue(bool(isinstance(service, ServiceBase) for service in self._services._transient_services)) + + def test_get_transient(self): + print(f'{__name__}.test_get_transient:') + self._check_general_requirements() + self._add_logger() + + self._services.add_transient(PublisherBase, Publisher) + publisher: Publisher = self._services.get_service(PublisherBase) + self.assertIsNotNone(publisher) + self.assertTrue(isinstance(publisher, Publisher)) + self.assertTrue(isinstance(publisher, PublisherBase)) + self.assertTrue(isinstance(publisher, ServiceBase)) + + self.assertTrue(isinstance(publisher._logger, Logger)) + self.assertTrue(isinstance(publisher._logger, LoggerBase)) + self.assertTrue(isinstance(publisher._logger, ServiceBase)) diff --git a/src/tests/tester.py b/src/tests/tester.py index e4eb313e..dfb11e49 100644 --- a/src/tests/tester.py +++ b/src/tests/tester.py @@ -1,79 +1,45 @@ -import os -import sys -import traceback +import unittest -from termcolor import colored - -from sh_edraft.configuration import ApplicationHost -from tests.logger import LoggerTest -from tests.publisher import PublisherTest -from tests.service_provider import ServiceProviderTest +from tests.logging.logger import LoggerTest +from tests.publishing.publisher import PublisherTest +from tests.service_providing.service_provider import ServiceProviderTest class Tester: def __init__(self): - self._app_host = ApplicationHost() + self._suite = unittest.TestSuite() - self._error: bool = False + def create(self): + # providing + self._suite.addTest(ServiceProviderTest('test_create')) + self._suite.addTest(ServiceProviderTest('test_add_singleton')) + self._suite.addTest(ServiceProviderTest('test_get_singleton')) + self._suite.addTest(ServiceProviderTest('test_add_scoped')) + self._suite.addTest(ServiceProviderTest('test_get_scoped')) + self._suite.addTest(ServiceProviderTest('test_add_transient')) + self._suite.addTest(ServiceProviderTest('test_get_transient')) - @staticmethod - def disable_print(): - sys.stdout = open(os.devnull, 'w') + # logging + self._suite.addTest(LoggerTest('test_create')) + self._suite.addTest(LoggerTest('test_header')) + self._suite.addTest(LoggerTest('test_trace')) + self._suite.addTest(LoggerTest('test_debug')) + self._suite.addTest(LoggerTest('test_info')) + self._suite.addTest(LoggerTest('test_warn')) + self._suite.addTest(LoggerTest('test_error')) + self._suite.addTest(LoggerTest('test_fatal')) - @staticmethod - def enable_print(): - sys.stdout = sys.__stdout__ - - def success(self, message: str): - self.enable_print() - print(colored(message, 'green')) - self.disable_print() - - def failed(self, message: str): - self.enable_print() - print(colored(message, 'red')) - self.disable_print() - - def exception(self): - self.enable_print() - print(colored(traceback.format_exc(), 'red')) - self.disable_print() - - def create(self): pass + # publishing + self._suite.addTest(PublisherTest('test_create')) def start(self): - if not self._error: - try: - LoggerTest.start(self._app_host) - self.success(f'{LoggerTest.__name__} test succeeded.') - except Exception as e: - self._error = True - self.failed(f'{LoggerTest.__name__} test failed!\n{e}') - self.exception() - - if not self._error: - try: - ServiceProviderTest.start(self._app_host.services) - self.success(f'{ServiceProviderTest.__name__} test succeeded.') - except Exception as e: - self._error = True - self.failed(f'{ServiceProviderTest.__name__} test failed!\n{e}') - self.exception() - - if not self._error: - try: - PublisherTest.start(self._app_host.services) - self.success(f'{PublisherTest.__name__} test succeeded.') - except Exception as e: - self._error = True - self.failed(f'{PublisherTest.__name__} test failed!\n{e}') - self.exception() + runner = unittest.TextTestRunner() + runner.run(self._suite) + # unittest.main() if __name__ == '__main__': tester = Tester() tester.create() - tester.disable_print() tester.start() - tester.enable_print()