2021.4.2 #12

Merged
edraft merged 22 commits from 2021.4.2 into 2021.4 2021-03-29 15:48:59 +02:00
111 changed files with 1095 additions and 522 deletions

View File

@ -4,7 +4,7 @@
"Version": {
"Major": "2021",
"Minor": "04",
"Micro": "01-15"
"Micro": "02"
},
"Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -15,11 +15,11 @@ __title__ = 'sh_cpl.cpl'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.application'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -23,9 +23,7 @@ from collections import namedtuple
from .application_abc import ApplicationABC
from .application_builder import ApplicationBuilder
from .application_builder_abc import ApplicationBuilderABC
from .application_runtime import ApplicationRuntime
from .application_runtime_abc import ApplicationRuntimeABC
from .startup_abc import StartupABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,21 +1,21 @@
from abc import ABC, abstractmethod
from typing import Optional
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.environment import ApplicationEnvironmentABC
class ApplicationABC(ABC):
@abstractmethod
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
"""
ABC of application
"""
self._configuration: Optional[ConfigurationABC] = config
self._runtime: Optional[ApplicationRuntimeABC] = runtime
self._environment: Optional[ApplicationEnvironmentABC] = self._configuration.environment
self._services: Optional[ServiceProviderABC] = services
def run(self):

View File

@ -2,10 +2,9 @@ from typing import Type, Optional
from cpl.application.application_abc import ApplicationABC
from cpl.application.application_builder_abc import ApplicationBuilderABC
from cpl.application.application_runtime import ApplicationRuntime
from cpl.application.startup_abc import StartupABC
from cpl.configuration import Configuration
from cpl.dependency_injection import ServiceProvider
from cpl.configuration.configuration import Configuration
edraft marked this conversation as resolved Outdated

Direci import change to from cpl.configuration.configuration import Configuration

Direci import change to from cpl.configuration.configuration import Configuration
from cpl.dependency_injection.service_collection import ServiceCollection
class ApplicationBuilder(ApplicationBuilderABC):
@ -19,8 +18,8 @@ class ApplicationBuilder(ApplicationBuilderABC):
self._startup: Optional[StartupABC] = None
self._configuration = Configuration()
self._runtime = ApplicationRuntime()
self._services = ServiceProvider(self._configuration, self._runtime)
self._environment = self._configuration.environment
self._services = ServiceCollection(self._configuration)
def use_startup(self, startup: Type[StartupABC]):
"""
@ -28,7 +27,7 @@ class ApplicationBuilder(ApplicationBuilderABC):
:param startup:
:return:
"""
self._startup = startup(self._configuration, self._runtime, self._services)
self._startup = startup(self._configuration, self._services)
def build(self) -> ApplicationABC:
"""
@ -39,4 +38,4 @@ class ApplicationBuilder(ApplicationBuilderABC):
self._startup.configure_configuration()
self._startup.configure_services()
return self._app(self._configuration, self._runtime, self._services)
return self._app(self._configuration, self._services.build_service_provider())

View File

@ -1,52 +0,0 @@
import pathlib
from datetime import datetime
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
class ApplicationRuntime(ApplicationRuntimeABC):
def __init__(self):
"""
Representation of the application runtime
"""
ApplicationRuntimeABC.__init__(self)
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
self._working_directory = pathlib.Path().absolute()
self._runtime_directory = pathlib.Path(__file__).parent.absolute()
@property
def start_time(self) -> datetime:
return self._start_time
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, end_time: datetime):
self._end_time = end_time
@property
def date_time_now(self) -> datetime:
return datetime.now()
@property
def working_directory(self) -> str:
return self._working_directory
def set_working_directory(self, path: str = ''):
if path != '':
self._working_directory = path
return
self._working_directory = pathlib.Path().absolute()
@property
def runtime_directory(self) -> str:
return self._runtime_directory
def set_runtime_directory(self, file: str):
self._runtime_directory = pathlib.Path(file).parent.absolute()

View File

@ -1,49 +0,0 @@
from abc import ABC, abstractmethod
from datetime import datetime
class ApplicationRuntimeABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC for application runtime
"""
pass
@property
@abstractmethod
def start_time(self) -> datetime: pass
@start_time.setter
@abstractmethod
def start_time(self, start_time: datetime): pass
@property
@abstractmethod
def end_time(self): pass
@end_time.setter
@abstractmethod
def end_time(self, end_time: datetime): pass
@property
@abstractmethod
def date_time_now(self) -> datetime: pass
@property
@abstractmethod
def working_directory(self) -> str: pass
@property
@abstractmethod
def runtime_directory(self) -> str: pass
@abstractmethod
def set_runtime_directory(self, runtime_directory: str):
"""
Sets the current runtime directory
:param runtime_directory:
:return:
"""
pass

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.configuration'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -27,4 +27,4 @@ from .configuration_variable_name_enum import ConfigurationVariableNameEnum
from .console_argument import ConsoleArgument
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -11,7 +11,7 @@ from cpl.configuration.console_argument import ConsoleArgument
from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment import ApplicationEnvironment
from cpl.environment.environment_abc import ApplicationEnvironmentABC
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.environment.environment_name_enum import EnvironmentNameEnum

View File

@ -4,7 +4,7 @@ from typing import Type, Union, Optional
from cpl.configuration.console_argument import ConsoleArgument
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.environment.environment_abc import ApplicationEnvironmentABC
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
class ConfigurationABC(ABC):
@ -82,8 +82,7 @@ class ConfigurationABC(ABC):
pass
@abstractmethod
def get_configuration(self, search_type: Union[str, Type[ConfigurationModelABC]]) -> Union[
str, Callable[ConfigurationModelABC]]:
def get_configuration(self, search_type: Union[str, Type[ConfigurationModelABC]]) -> Union[str, Callable[ConfigurationModelABC]]:
"""
Returns value in configuration by given type
:param search_type:

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.console'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -27,4 +27,4 @@ from .foreground_color_enum import ForegroundColorEnum
from .spinner_thread import SpinnerThread
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.database'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -25,4 +25,4 @@ from .database_settings import DatabaseSettings
from .database_settings_name_enum import DatabaseSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.database.connection'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -24,4 +24,4 @@ from .database_connection import DatabaseConnection
from .database_connection_abc import DatabaseConnectionABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.database.context'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -24,4 +24,4 @@ from .database_context import DatabaseContext
from .database_context_abc import DatabaseContextABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -6,6 +6,10 @@ from sqlalchemy.orm import Session
class DatabaseContextABC(ABC):
@abstractmethod
def __init__(self, *args):
pass
@property
@abstractmethod
def engine(self) -> engine: pass

View File

@ -15,14 +15,17 @@ __title__ = 'cpl.dependency_injection'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
from .service_abc import ServiceABC
from .service_collection import ServiceCollection
from .service_collection_abc import ServiceCollectionABC
from .service_descriptor import ServiceDescriptor
from .service_lifetime_enum import ServiceLifetimeEnum
from .service_provider import ServiceProvider
from .service_provider_abc import ServiceProviderABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,11 +0,0 @@
from abc import ABC, abstractmethod
class ServiceABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC to represent a service
"""
pass

View File

@ -0,0 +1,65 @@
from typing import Union, Type, Callable, Optional
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.database.database_settings import DatabaseSettings
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC
from cpl.dependency_injection.service_descriptor import ServiceDescriptor
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
from cpl.dependency_injection.service_provider import ServiceProvider
from cpl.utils.credential_manager import CredentialManager
class ServiceCollection(ServiceCollectionABC):
def __init__(self, config: ConfigurationABC):
ServiceCollectionABC.__init__(self)
self._configuration: ConfigurationABC = config
self._database_context: Optional[DatabaseContextABC] = None
self._service_descriptors: list[ServiceDescriptor] = []
def _add_descriptor(self, service: Union[type, object], lifetime: ServiceLifetimeEnum):
found = False
for descriptor in self._service_descriptors:
if isinstance(service, descriptor.service_type):
found = True
if found:
service_type = service
if not isinstance(service, type):
service_type = type(service)
raise Exception(f'Service of type {service_type} already exists')
self._service_descriptors.append(ServiceDescriptor(service, lifetime))
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
self._database_context = db_context_type(db_settings)
self._database_context.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials))
def add_singleton(self, service_type: Union[type, object], service: Union[type, object] = None):
impl = None
if service is not None:
if isinstance(service, type):
impl = self.build_service_provider().build_service(service)
self._add_descriptor(impl, ServiceLifetimeEnum.singleton)
else:
if isinstance(service_type, type):
impl = self.build_service_provider().build_service(service_type)
self._add_descriptor(impl, ServiceLifetimeEnum.singleton)
def add_scoped(self, service_type: Type, service: Callable = None):
raise Exception('Not implemented')
def add_transient(self, service_type: Union[type], service: Union[type] = None):
if service is not None:
self._add_descriptor(service, ServiceLifetimeEnum.transient)
else:
self._add_descriptor(service_type, ServiceLifetimeEnum.transient)
def build_service_provider(self) -> ServiceProviderABC:
return ServiceProvider(self._service_descriptors, self._configuration, self._database_context)

View File

@ -0,0 +1,64 @@
from abc import abstractmethod, ABC
from collections import Callable
from typing import Type
from cpl.database.database_settings import DatabaseSettings
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
class ServiceCollectionABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC for service providing
"""
pass
@abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC], db_settings: DatabaseSettings):
"""
Adds database context
:param db_context:
:param db_settings:
:return:
"""
pass
@abstractmethod
def add_transient(self, service_type: Type, service: Callable = None):
"""
Adds a service with transient lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_scoped(self, service_type: Type, service: Callable = None):
"""
Adds a service with scoped lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_singleton(self, service_type: Type, service: Callable = None):
"""
Adds a service with singleton lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def build_service_provider(self) -> ServiceProviderABC:
"""
Creates instance of the service provider
"""
pass

View File

@ -0,0 +1,33 @@
from typing import Union, Optional
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
class ServiceDescriptor:
def __init__(self, implementation: Union[type, Optional[object]], lifetime: ServiceLifetimeEnum):
self._service_type = implementation
self._implementation = implementation
self._lifetime = lifetime
if not isinstance(implementation, type):
self._service_type = type(implementation)
else:
self._implementation = None
@property
def service_type(self) -> type:
return self._service_type
@property
def implementation(self) -> Union[type, Optional[object]]:
return self._implementation
@implementation.setter
def implementation(self, implementation: Union[type, Optional[object]]):
self._implementation = implementation
@property
def lifetime(self) -> ServiceLifetimeEnum:
return self._lifetime

View File

@ -0,0 +1,8 @@
from enum import Enum
class ServiceLifetimeEnum(Enum):
singleton = 0
scoped = 1 # not supported yet
transient = 2

View File

@ -1,45 +1,61 @@
from collections import Callable
from inspect import signature, Parameter
from typing import Type, Optional, Union
from typing import Optional
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.environment.environment_abc import ApplicationEnvironmentABC
from cpl.dependency_injection.service_descriptor import ServiceDescriptor
from cpl.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
class ServiceProvider(ServiceProviderABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC):
"""
Service for service providing
:param runtime:
"""
def __init__(self, service_descriptors: list[ServiceDescriptor], config: ConfigurationABC, db_context: Optional[DatabaseContextABC]):
ServiceProviderABC.__init__(self)
self._service_descriptors: list[ServiceDescriptor] = service_descriptors
self._configuration: ConfigurationABC = config
self._runtime: ApplicationRuntimeABC = runtime
self._database_context: Optional[DatabaseContextABC] = None
self._database_context = db_context
self._transient_services: dict[Type[ServiceABC], Callable[ServiceABC]] = {}
self._scoped_services: dict[Type[ServiceABC], Callable[ServiceABC]] = {}
self._singleton_services: dict[Type[ServiceABC], Callable[ServiceABC], ServiceABC] = {}
def _find_service(self, service_type: type) -> [ServiceDescriptor]:
for descriptor in self._service_descriptors:
if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
return descriptor
def _create_instance(self, service: Union[Callable[ServiceABC], ServiceABC]) -> Callable[ServiceABC]:
"""
Creates an instance of given type
:param service:
:return:
"""
sig = signature(service.__init__)
return None
def _get_service(self, parameter: Parameter) -> object:
for descriptor in self._service_descriptors:
if descriptor.service_type == parameter.annotation or issubclass(descriptor.service_type, parameter.annotation):
if descriptor.implementation is not None:
return descriptor.implementation
implementation = self.build_service(descriptor.service_type)
if descriptor.lifetime == ServiceLifetimeEnum.singleton:
descriptor.implementation = implementation
return implementation
def build_service(self, service_type: type) -> object:
for descriptor in self._service_descriptors:
if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
if descriptor.implementation is not None:
service_type = type(descriptor.implementation)
else:
service_type = descriptor.service_type
break
sig = signature(service_type.__init__)
params = []
for param in sig.parameters.items():
parameter = param[1]
if parameter.name != 'self' and parameter.annotation != Parameter.empty:
if issubclass(parameter.annotation, ApplicationRuntimeABC):
params.append(self._runtime)
if issubclass(parameter.annotation, ServiceProviderABC):
params.append(self)
elif issubclass(parameter.annotation, ApplicationEnvironmentABC):
params.append(self._configuration.environment)
@ -53,70 +69,22 @@ class ServiceProvider(ServiceProviderABC):
elif issubclass(parameter.annotation, ConfigurationABC):
params.append(self._configuration)
elif issubclass(parameter.annotation, ServiceProviderABC):
params.append(self)
else:
params.append(self.get_service(parameter.annotation))
params.append(self._get_service(parameter))
return service(*params)
return service_type(*params)
def add_db_context(self, db_context: Type[DatabaseContextABC]):
self._database_context = self._create_instance(db_context)
def get_service(self, service_type: type) -> Optional[Callable[object]]:
result = self._find_service(service_type)
def get_db_context(self) -> Callable[DatabaseContextABC]:
return self._database_context
if result is None:
return None
def add_transient(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None):
if service is None:
self._transient_services[service_type] = service_type
else:
self._transient_services[service_type] = service
if result.implementation is not None:
return result.implementation
def add_scoped(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None):
if service is None:
self._scoped_services[service_type] = service_type
else:
self._scoped_services[service_type] = service
implementation = self.build_service(service_type)
if result.lifetime == ServiceLifetimeEnum.singleton:
result.implementation = implementation
def add_singleton(self, service_type: Type[ServiceABC], service: Callable[ServiceABC] = None):
for known_service in self._singleton_services:
if type(known_service) == service_type:
raise Exception(f'Service with type {service_type} already exists')
if service is None:
self._singleton_services[service_type] = self._create_instance(service_type)
else:
self._singleton_services[service_type] = self._create_instance(service)
def get_service(self, instance_type: Type) -> Callable[ServiceABC]:
if issubclass(instance_type, ServiceProviderABC):
return self
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 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 service == instance_type and isinstance(self._singleton_services[service], instance_type):
return self._singleton_services[service]
def remove_service(self, instance_type: Type[ServiceABC]):
for service in self._transient_services:
if service == instance_type and isinstance(self._transient_services[service], type(instance_type)):
del self._transient_services[service]
return
for service in self._scoped_services:
if service == instance_type and isinstance(self._scoped_services[service], type(instance_type)):
del self._scoped_services[service]
return
for service in self._singleton_services:
if service == instance_type and isinstance(self._singleton_services[service], instance_type):
del self._singleton_services[service]
return
return implementation

View File

@ -1,9 +1,6 @@
from abc import abstractmethod, ABC
from collections import Callable
from typing import Type
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_abc import ServiceABC
from typing import Type, Optional
class ServiceProviderABC(ABC):
@ -16,66 +13,19 @@ class ServiceProviderABC(ABC):
pass
@abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC]):
def build_service(self, service_type: type) -> object:
"""
Adds database context
:param db_context:
:return:
"""
pass
@abstractmethod
def get_db_context(self) -> Callable[DatabaseContextABC]:
""""
Returns database context
:return Callable[DatabaseContextABC]:
"""
pass
@abstractmethod
def add_transient(self, service_type: Type, service: Callable = None):
"""
Adds a service with transient lifetime
Creates instance of given type
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_scoped(self, service_type: Type, service: Callable = None):
"""
Adds a service with scoped lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def add_singleton(self, service_type: Type, service: Callable = None):
"""
Adds a service with singleton lifetime
:param service_type:
:param service:
:return:
"""
pass
@abstractmethod
def get_service(self, instance_type: Type) -> Callable[ServiceABC]:
def get_service(self, instance_type: Type) -> Optional[Callable[object]]:
"""
Returns instance of given type
:param instance_type:
:return:
"""
pass
@abstractmethod
def remove_service(self, instance_type: type):
"""
Removes service
:param instance_type:
:return:
"""
pass

View File

@ -15,14 +15,14 @@ __title__ = 'cpl.environment'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
from .environment_abc import ApplicationEnvironmentABC
from .application_environment_abc import ApplicationEnvironmentABC
from .environment_name_enum import EnvironmentNameEnum
from .application_environment import ApplicationEnvironment
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,7 +1,9 @@
import pathlib
from datetime import datetime
from socket import gethostname
from typing import Optional
from cpl.environment.environment_abc import ApplicationEnvironmentABC
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.environment.environment_name_enum import EnvironmentNameEnum
@ -20,6 +22,11 @@ class ApplicationEnvironment(ApplicationEnvironmentABC):
self._customer: Optional[str] = None
self._content_root_path: Optional[str] = crp
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
self._working_directory = pathlib.Path().absolute()
self._runtime_directory = pathlib.Path(__file__).parent.absolute()
@property
def environment_name(self) -> str:
return str(self._environment_name.value)
@ -55,3 +62,37 @@ class ApplicationEnvironment(ApplicationEnvironmentABC):
@property
def host_name(self):
return gethostname()
@property
def start_time(self) -> datetime:
return self._start_time
@property
def end_time(self) -> datetime:
return self._end_time
@end_time.setter
def end_time(self, end_time: datetime):
self._end_time = end_time
@property
def date_time_now(self) -> datetime:
return datetime.now()
@property
def working_directory(self) -> str:
return self._working_directory
def set_working_directory(self, path: str = ''):
if path != '':
self._working_directory = path
return
self._working_directory = pathlib.Path().absolute()
@property
def runtime_directory(self) -> str:
return self._runtime_directory
def set_runtime_directory(self, file: str):
self._runtime_directory = pathlib.Path(file).parent.absolute()

View File

@ -1,4 +1,5 @@
from abc import ABC, abstractmethod
from datetime import datetime
class ApplicationEnvironmentABC(ABC):
@ -45,3 +46,40 @@ class ApplicationEnvironmentABC(ABC):
@property
@abstractmethod
def host_name(self) -> str: pass
@property
@abstractmethod
def start_time(self) -> datetime: pass
@start_time.setter
@abstractmethod
def start_time(self, start_time: datetime): pass
@property
@abstractmethod
def end_time(self): pass
@end_time.setter
@abstractmethod
def end_time(self, end_time: datetime): pass
@property
@abstractmethod
def date_time_now(self) -> datetime: pass
@property
@abstractmethod
def working_directory(self) -> str: pass
@property
@abstractmethod
def runtime_directory(self) -> str: pass
@abstractmethod
def set_runtime_directory(self, runtime_directory: str):
"""
Sets the current runtime directory
:param runtime_directory:
:return:
"""
pass

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.logging'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -27,4 +27,4 @@ from .logging_settings import LoggingSettings
from .logging_settings_name_enum import LoggingSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,16 +1,14 @@
from abc import abstractmethod
from cpl.dependency_injection.service_abc import ServiceABC
from abc import abstractmethod, ABC
class LoggerABC(ServiceABC):
class LoggerABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC for logging
"""
ServiceABC.__init__(self)
ABC.__init__(self)
@abstractmethod
def header(self, string: str):

View File

@ -3,9 +3,9 @@ import os
import traceback
from string import Template
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.logging.logger_abc import LoggerABC
from cpl.logging.logging_level_enum import LoggingLevelEnum
from cpl.logging.logging_settings import LoggingSettings
@ -14,7 +14,7 @@ from cpl.time.time_format_settings import TimeFormatSettings
class Logger(LoggerABC):
def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_runtime: ApplicationRuntimeABC):
def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, env: ApplicationEnvironmentABC):
"""
Service for logging
:param logging_settings:
@ -23,13 +23,13 @@ class Logger(LoggerABC):
"""
LoggerABC.__init__(self)
self._app_runtime = app_runtime
self._env = env
self._log_settings: LoggingSettings = logging_settings
self._time_format_settings: TimeFormatSettings = time_format
self._log = Template(self._log_settings.filename).substitute(
date_time_now=self._app_runtime.date_time_now.strftime(self._time_format_settings.date_time_format),
start_time=self._app_runtime.start_time.strftime(self._time_format_settings.date_time_log_format)
date_time_now=self._env.date_time_now.strftime(self._time_format_settings.date_time_format),
start_time=self._env.start_time.strftime(self._time_format_settings.date_time_log_format)
)
self._path = self._log_settings.path
self._level = self._log_settings.level

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.mailing'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -27,4 +27,4 @@ from .email_client_settings import EMailClientSettings
from .email_client_settings_name_enum import EMailClientSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,17 +1,16 @@
from abc import abstractmethod
from abc import abstractmethod, ABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.mailing.email import EMail
class EMailClientABC(ServiceABC):
class EMailClientABC(ABC):
@abstractmethod
def __init__(self):
"""
ABC to send emails
"""
ServiceABC.__init__(self)
ABC.__init__(self)
@abstractmethod
def connect(self):

View File

@ -2,7 +2,7 @@ import ssl
from smtplib import SMTP
from typing import Optional
from cpl.environment.environment_abc import ApplicationEnvironmentABC
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email import EMail
from cpl.mailing.email_client_abc import EMailClientABC

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.time'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -24,4 +24,4 @@ from .time_format_settings import TimeFormatSettings
from .time_format_settings_names_enum import TimeFormatSettingsNamesEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl.utils'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -25,4 +25,4 @@ from .string import String
from .pip import Pip
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,7 +15,7 @@ __title__ = 'sh_cpl.cpl_cli'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -29,4 +29,4 @@ from .main import main
from .startup import Startup
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,7 +1,6 @@
from typing import Optional
from cpl.application.application_abc import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console
from cpl.dependency_injection import ServiceProviderABC
@ -22,11 +21,11 @@ from cpl_cli.command.version_service import VersionService
class CLI(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
"""
CPL CLI
"""
ApplicationABC.__init__(self, config, runtime, services)
ApplicationABC.__init__(self, config, services)
self._command_handler: Optional[CommandHandler] = None

View File

@ -15,7 +15,7 @@ __title__ = 'cpl_cli.command'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -28,4 +28,4 @@ from .publish_service import PublishService
from .version_service import VersionService
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,4 +1,3 @@
from cpl.console.console import Console
from cpl_cli.command_abc import CommandABC
from cpl_cli.publish.publisher_abc import PublisherABC
@ -21,4 +20,3 @@ class BuildService(CommandABC):
:return:
"""
self._publisher.build()
Console.write('\n')

View File

@ -1,7 +1,6 @@
import os
from collections import Callable
from cpl.application.application_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console
@ -18,11 +17,10 @@ from cpl_cli.templates.template_file_abc import TemplateFileABC
class GenerateService(CommandABC):
def __init__(self, configuration: ConfigurationABC, runtime: ApplicationRuntimeABC):
def __init__(self, configuration: ConfigurationABC):
"""
Service for the CLI command generate
:param configuration:
:param runtime:
"""
CommandABC.__init__(self)
@ -54,7 +52,7 @@ class GenerateService(CommandABC):
}
self._config = configuration
self._runtime = runtime
self._env = self._config.environment
@staticmethod
def _help(message: str):
@ -105,7 +103,7 @@ class GenerateService(CommandABC):
template = template(class_name, schematic, self._schematics[schematic]["Upper"], rel_path)
file_path = os.path.join(self._runtime.working_directory, template.path, template.name)
file_path = os.path.join(self._env.working_directory, template.path, template.name)
if not os.path.isdir(os.path.dirname(file_path)):
os.makedirs(os.path.dirname(file_path))
@ -113,9 +111,9 @@ class GenerateService(CommandABC):
Console.error(f'{String.first_to_upper(schematic)} already exists!')
exit()
message = f'Creating {self._runtime.working_directory}/{template.path}/{template.name}'
message = f'Creating {self._env.working_directory}/{template.path}/{template.name}'
if template.path == '':
message = f'Creating {self._runtime.working_directory}/{template.name}'
message = f'Creating {self._env.working_directory}/{template.name}'
Console.spinner(
message,
@ -148,5 +146,3 @@ class GenerateService(CommandABC):
else:
self._help('Usage: cpl generate <schematic> [options]')
exit()
Console.write('\n')

View File

@ -35,5 +35,3 @@ class HelpService(CommandABC):
Console.write(f'\n\t{name} ')
Console.set_foreground_color(ForegroundColorEnum.default)
Console.write(f'{description}')
Console.write('\n')

View File

@ -4,9 +4,9 @@ import subprocess
from packaging import version
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip
from cpl_cli.cli_settings import CLISettings
from cpl_cli.command_abc import CommandABC
@ -18,18 +18,18 @@ from cpl_cli.error import Error
class InstallService(CommandABC):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings, project_settings: ProjectSettings,
def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings, project_settings: ProjectSettings,
cli_settings: CLISettings):
"""
Service for the CLI command install
:param runtime:
:param env:
:param build_settings:
:param project_settings:
:param cli_settings:
"""
CommandABC.__init__(self)
self._runtime = runtime
self._env = env
self._build_settings = build_settings
self._project_settings = project_settings
self._cli_settings = cli_settings
@ -147,7 +147,7 @@ class InstallService(CommandABC):
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
}
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project_file:
with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2))
project_file.close()
@ -163,5 +163,3 @@ class InstallService(CommandABC):
self._install_project()
else:
self._install_package(args[0])
Console.write('\n')

View File

@ -7,7 +7,6 @@ from packaging import version
import cpl
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console
@ -20,7 +19,8 @@ from cpl_cli.configuration.version_settings_name_enum import VersionSettingsName
from cpl_cli.templates.new.console.license import LicenseTemplate
from cpl_cli.templates.new.console.readme_py import ReadmeTemplate
from cpl_cli.templates.new.console.src.application import ApplicationTemplate
from cpl_cli.templates.new.console.src.main import MainWithApplicationHostAndStartupTemplate, MainWithoutApplicationHostTemplate, MainWithApplicationHostTemplate
from cpl_cli.templates.new.console.src.main import MainWithApplicationHostAndStartupTemplate, \
MainWithoutApplicationBaseTemplate, MainWithApplicationBaseTemplate, MainWithDependencyInjection
from cpl_cli.templates.new.console.src.startup import StartupTemplate
from cpl_cli.templates.new.console.src.tests.init import TestsInitTemplate
from cpl_cli.templates.template_file_abc import TemplateFileABC
@ -28,16 +28,15 @@ from cpl_cli.templates.template_file_abc import TemplateFileABC
class NewService(CommandABC):
def __init__(self, configuration: ConfigurationABC, runtime: ApplicationRuntimeABC):
def __init__(self, configuration: ConfigurationABC):
"""
Service for the CLI command new
:param configuration:
:param runtime:
"""
CommandABC.__init__(self)
self._config = configuration
self._runtime = runtime
self._env = self._config.environment
self._project: ProjectSettings = ProjectSettings()
self._project_dict = {}
@ -127,34 +126,33 @@ class NewService(CommandABC):
Gets project path
:return:
"""
project_path = os.path.join(self._runtime.working_directory, self._project.name)
project_path = os.path.join(self._env.working_directory, self._project.name)
if os.path.isdir(project_path) and len(os.listdir(project_path)) > 0:
Console.error('Project path is not empty\n')
return None
return project_path
def _get_project_informations(self):
def _get_project_information(self):
"""
Gets project informations from user
Gets project information's from user
:return:
"""
result = Console.read('Do you want to use application host? (y/n) ')
result = Console.read('Do you want to use application base? (y/n) ')
if result.lower() == 'y':
self._use_application_api = True
if self._use_application_api:
result = Console.read('Do you want to use startup? (y/n) ')
if result.lower() == 'y':
self._use_startup = True
result = Console.read('Do you want to use service providing? (y/n) ')
if result.lower() == 'y':
self._use_service_providing = True
if self._use_application_api:
result = Console.read('Do you want to use startup? (y/n) ')
if result.lower() == 'y':
self._use_startup = True
Console.set_foreground_color(ForegroundColorEnum.default)
# else:
# result = Console.read('Do you want to use service providing? (y/n) ')
# if result.lower() == 'y':
# self._use_service_providing = True
def _build_project_dir(self, project_path: str):
"""
Builds the project files
@ -173,15 +171,20 @@ class NewService(CommandABC):
ReadmeTemplate(),
TestsInitTemplate()
]
if self._use_application_api:
templates.append(ApplicationTemplate())
if self._use_startup:
templates.append(StartupTemplate())
templates.append(MainWithApplicationHostAndStartupTemplate())
else:
templates.append(MainWithApplicationHostTemplate())
templates.append(MainWithApplicationBaseTemplate())
else:
templates.append(MainWithoutApplicationHostTemplate())
if self._use_service_providing:
templates.append(MainWithDependencyInjection())
else:
templates.append(MainWithoutApplicationBaseTemplate())
for template in templates:
Console.spinner(
@ -226,7 +229,7 @@ class NewService(CommandABC):
if path is None:
return
self._get_project_informations()
self._get_project_information()
try:
self._build_project_dir(path)
except Exception as e:
@ -249,5 +252,3 @@ class NewService(CommandABC):
else:
self._help('Usage: cpl new <schematic> [options]')
exit()
Console.write('\n')

View File

@ -21,4 +21,3 @@ class PublishService(CommandABC):
:return:
"""
self._publisher.publish()
Console.write('\n')

View File

@ -2,9 +2,9 @@ import json
import os
import subprocess
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip
from cpl_cli.command_abc import CommandABC
from cpl_cli.configuration.build_settings import BuildSettings
@ -14,17 +14,17 @@ from cpl_cli.configuration.settings_helper import SettingsHelper
class UninstallService(CommandABC):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings,
def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings,
project_settings: ProjectSettings):
"""
Service for the CLI command uninstall
:param runtime:
:param env:
:param build_settings:
:param project_settings:
"""
CommandABC.__init__(self)
self._runtime = runtime
self._env = env
self._build_settings = build_settings
self._project_settings = project_settings
@ -74,7 +74,7 @@ class UninstallService(CommandABC):
ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings),
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
}
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project_file:
with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2))
project_file.close()

View File

@ -2,9 +2,9 @@ import json
import os
import subprocess
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl.utils.pip import Pip
from cpl_cli.cli_settings import CLISettings
from cpl_cli.command_abc import CommandABC
@ -16,20 +16,20 @@ from cpl_cli.configuration.settings_helper import SettingsHelper
class UpdateService(CommandABC):
def __init__(self,
runtime: ApplicationRuntimeABC,
env: ApplicationEnvironmentABC,
build_settings: BuildSettings,
project_settings: ProjectSettings,
cli_settings: CLISettings):
"""
Service for the CLI command update
:param runtime:
:param env:
:param build_settings:
:param project_settings:
:param cli_settings:
"""
CommandABC.__init__(self)
self._runtime = runtime
self._env = env
self._build_settings = build_settings
self._project_settings = project_settings
self._cli_settings = cli_settings
@ -117,7 +117,7 @@ class UpdateService(CommandABC):
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
}
with open(os.path.join(self._runtime.working_directory, 'cpl.json'), 'w') as project:
with open(os.path.join(self._env.working_directory, 'cpl.json'), 'w') as project:
project.write(json.dumps(config, indent=2))
project.close()
@ -131,5 +131,3 @@ class UpdateService(CommandABC):
self._check_project_dependencies()
self._check_outdated()
Pip.reset_executable()
Console.write('\n')

View File

@ -1,13 +1,11 @@
from abc import abstractmethod
from cpl.dependency_injection.service_abc import ServiceABC
from abc import abstractmethod, ABC
class CommandABC(ServiceABC):
class CommandABC(ABC):
@abstractmethod
def __init__(self):
ServiceABC.__init__(self)
ABC.__init__(self)
@abstractmethod
def run(self, args: list[str]): pass

View File

@ -1,25 +1,25 @@
import os
from abc import ABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl_cli.error import Error
from cpl_cli.command_model import CommandModel
class CommandHandler(ServiceABC):
class CommandHandler(ABC):
def __init__(self, runtime: ApplicationRuntimeABC, config: ConfigurationABC, services: ServiceProviderABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
"""
Service to handle incoming commands and args
:param runtime:
:param config:
:param services:
"""
ServiceABC.__init__(self)
ABC.__init__(self)
self._runtime = runtime
self._config = config
self._env = self._config.environment
self._services = services
self._commands: list[CommandModel] = []
@ -43,7 +43,7 @@ class CommandHandler(ServiceABC):
"""
for command in self._commands:
if cmd == command.name or cmd in command.aliases:
if command.is_project_needed and not os.path.isfile(os.path.join(self._runtime.working_directory, 'cpl.json')):
if command.is_project_needed and not os.path.isfile(os.path.join(self._env.working_directory, 'cpl.json')):
Error.error('The command requires to be run in an CPL project, but a project could not be found.')
return
@ -51,3 +51,4 @@ class CommandHandler(ServiceABC):
self._config.add_json_file('cpl.json', optional=True, output=False)
self._services.get_service(command.command).run(args)
Console.write('\n')

View File

@ -15,7 +15,7 @@ __title__ = 'cpl_cli.configuration'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -28,4 +28,4 @@ from .version_settings import VersionSettings
from .version_settings_name_enum import VersionSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.live_server'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,33 +1,33 @@
import os
import time
from abc import ABC
from contextlib import suppress
import psutil as psutil
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.console import Console
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.live_server.live_server_thread import LiveServerThread
class LiveServerService(ServiceABC, FileSystemEventHandler):
class LiveServerService(ABC, FileSystemEventHandler):
def __init__(self, runtime: ApplicationRuntimeABC, build_settings: BuildSettings):
def __init__(self, env: ApplicationEnvironmentABC, build_settings: BuildSettings):
"""
Service for the live development server
:param runtime:
:param env:
:param build_settings:
"""
ServiceABC.__init__(self)
ABC.__init__(self)
FileSystemEventHandler.__init__(self)
self._runtime = runtime
self._env = env
self._build_settings = build_settings
self._src_dir = os.path.join(self._runtime.working_directory, self._build_settings.source_path)
self._src_dir = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._ls_thread = None
self._observer = None

View File

@ -15,7 +15,7 @@ __title__ = 'cpl_cli.publish'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
@ -24,4 +24,4 @@ from .publisher_abc import PublisherABC
from .publisher_service import PublisherService
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -1,13 +1,11 @@
from abc import abstractmethod
from cpl.dependency_injection.service_abc import ServiceABC
from abc import abstractmethod, ABC
class PublisherABC(ServiceABC):
class PublisherABC(ABC):
@abstractmethod
def __init__(self):
ServiceABC.__init__(self)
ABC.__init__(self)
@property
@abstractmethod

View File

@ -7,9 +7,9 @@ import setuptools
from packaging import version
from setuptools import sandbox
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.console.foreground_color_enum import ForegroundColorEnum
from cpl.console.console import Console
from cpl.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.configuration.project_settings import ProjectSettings
from cpl_cli.publish.publisher_abc import PublisherABC
@ -19,21 +19,21 @@ from cpl_cli.templates.publish.setup_template import SetupTemplate
class PublisherService(PublisherABC):
def __init__(self, runtime: ApplicationRuntimeABC, project: ProjectSettings, build: BuildSettings):
def __init__(self, env: ApplicationEnvironmentABC, project: ProjectSettings, build: BuildSettings):
"""
Service to build or publish files for distribution
:param runtime:
:param env:
:param project:
:param build:
"""
PublisherABC.__init__(self)
self._runtime = runtime
self._env = env
self._project_settings = project
self._build_settings = build
self._source_path = os.path.join(self._runtime.working_directory, self._build_settings.source_path)
self._output_path = os.path.join(self._runtime.working_directory, self._build_settings.output_path)
self._source_path = os.path.join(self._env.working_directory, self._build_settings.source_path)
self._output_path = os.path.join(self._env.working_directory, self._build_settings.output_path)
self._included_files: list[str] = []
self._included_dirs: list[str] = []

View File

@ -1,7 +1,7 @@
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.application.startup_abc import StartupABC
from cpl.configuration.console_argument import ConsoleArgument
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl_cli.command.build_service import BuildService
from cpl_cli.command.generate_service import GenerateService
@ -22,21 +22,21 @@ from cpl_cli.publish.publisher_abc import PublisherABC
class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC):
def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self)
self._configuration = config
self._application_runtime = runtime
self._env = self._configuration.environment
self._services = services
self._application_runtime.set_runtime_directory(__file__)
self._env.set_runtime_directory(__file__)
def configure_configuration(self) -> ConfigurationABC:
self._configuration.argument_error_function = Error.error
self._configuration.add_environment_variables('PYTHON_')
self._configuration.add_environment_variables('CPL_')
self._configuration.add_json_file('appsettings.json', path=self._application_runtime.runtime_directory,
self._configuration.add_json_file('appsettings.json', path=self._env.runtime_directory,
optional=False, output=False)
self._configuration.add_console_argument(ConsoleArgument('', 'build', ['b', 'B'], ''))
self._configuration.add_console_argument(ConsoleArgument('', 'generate', ['g', 'G'], '', console_arguments=[
@ -80,4 +80,4 @@ class Startup(StartupABC):
self._services.add_transient(UpdateService)
self._services.add_transient(VersionService)
return self._services
return self._services.build_service_provider()

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.build'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.generate'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console.src'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -11,17 +11,16 @@ class ApplicationTemplate(TemplateFileABC):
self._name = 'application.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.application.application_abc import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.application import ApplicationABC
from cpl.configuration import ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, runtime, services)
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass

View File

@ -11,7 +11,7 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
self._name = 'main.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.application.application_builder import ApplicationBuilder
from cpl.application import ApplicationBuilder
from application import Application
from startup import Startup
@ -40,7 +40,7 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
return self._value
class MainWithApplicationHostTemplate(TemplateFileABC):
class MainWithApplicationBaseTemplate(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
@ -48,7 +48,7 @@ class MainWithApplicationHostTemplate(TemplateFileABC):
self._name = 'main.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.application.application_builder import ApplicationBuilder
from cpl.application import ApplicationBuilder
from application import Application
@ -75,7 +75,7 @@ class MainWithApplicationHostTemplate(TemplateFileABC):
return self._value
class MainWithoutApplicationHostTemplate(TemplateFileABC):
class MainWithoutApplicationBaseTemplate(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
@ -83,7 +83,7 @@ class MainWithoutApplicationHostTemplate(TemplateFileABC):
self._name = 'main.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.console.console import Console
from cpl.console import Console
def main():
@ -105,3 +105,49 @@ class MainWithoutApplicationHostTemplate(TemplateFileABC):
@property
def value(self) -> str:
return self._value
class MainWithDependencyInjection(TemplateFileABC):
def __init__(self):
TemplateFileABC.__init__(self)
self._name = 'main.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.configuration import Configuration, ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
return self._name
@property
def path(self) -> str:
return self._path
@property
def value(self) -> str:
return self._value

View File

@ -11,27 +11,25 @@ class StartupTemplate(TemplateFileABC):
self._name = 'startup.py'
self._path = 'src/'
self._value = textwrap.dedent("""\
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.application.startup_abc import StartupABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.application import StartupABC
from cpl.configuration import ConfigurationABC
from cpl.dependency_injection import ServiceProviderABC, ServiceCollectionABC
class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC):
def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self)
self._configuration = config
self._application_runtime = runtime
self._environment = self._configuration.environment
self._services = services
def configure_configuration(self) -> ConfigurationABC:
return self._configuration
def configure_services(self) -> ServiceProviderABC:
return self._services
return self._services.build_service_provider()
""")
@property

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.new.console.src.tests'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -15,11 +15,11 @@ __title__ = 'cpl_cli.templates.publish'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.4.1.post15'
__version__ = '2021.4.2'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='04', micro='01-15')
version_info = VersionInfo(major='2021', minor='04', micro='02')

View File

@ -6,6 +6,15 @@ def test_spinner():
time.sleep(2)
def test_console():
Console.write_line('Hello World')
Console.write('\nName: ')
Console.write_line(' Hello', Console.read_line())
Console.clear()
Console.write_at(5, 5, 'at 5, 5')
Console.write_at(10, 10, 'at 10, 10')
if __name__ == '__main__':
Console.write_line('Hello World\n')
Console.spinner('Test:', test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan,
@ -25,5 +34,6 @@ if __name__ == '__main__':
# cursor_foreground_color=ForegroundColorEnum.red
# )
# Console.write_line(f'You selected: {selected}')
# test_console()
Console.write_line()

View File

@ -1,13 +0,0 @@
from cpl.console.console import Console
from model.test_model import TestModel
def main():
Console.write_line('Hello World')
Console.write_line('Dies ist ein test')
test = TestModel()
if __name__ == '__main__':
main()

View File

@ -1,22 +0,0 @@
import time
from cpl.console import Console
class TestModel:
def __init__(self):
Console.spinner('Waiting: ', self._wait, 10)
option = Console.select('->', 'Select option: ', [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6'
])
Console.write_line('You selected', option)
@staticmethod
def _wait(count: int):
time.sleep(count)

View File

@ -0,0 +1,8 @@
{
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "TRACE",
"FileLogLevel": "TRACE"
}
}

View File

@ -0,0 +1,22 @@
{
"TimeFormatSettings": {
"DateFormat": "%Y-%m-%d",
"TimeFormat": "%H:%M:%S",
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
},
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "TRACE",
"FileLogLevel": "TRACE"
},
"DatabaseSettings": {
"AuthPlugin": "mysql_native_password",
"ConnectionString": "mysql+mysqlconnector://sh_cpl:$credentials@localhost/sh_cpl",
"Credentials": "MHZhc0Y2bjhKc1VUMWV0Qw==",
"Encoding": "utf8mb4"
}
}

View File

@ -0,0 +1,22 @@
{
"TimeFormatSettings": {
"DateFormat": "%Y-%m-%d",
"TimeFormat": "%H:%M:%S",
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
},
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "TRACE",
"FileLogLevel": "TRACE"
},
"DatabaseSettings": {
"AuthPlugin": "mysql_native_password",
"ConnectionString": "mysql+mysqlconnector://sh_cpl:$credentials@localhost/sh_cpl",
"Credentials": "MHZhc0Y2bjhKc1VUMWV0Qw==",
"Encoding": "utf8mb4"
}
}

View File

@ -0,0 +1,15 @@
{
"TimeFormatSettings": {
"DateFormat": "%Y-%m-%d",
"TimeFormat": "%H:%M:%S",
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
},
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "ERROR",
"FileLogLevel": "WARN"
}
}

View File

@ -1,6 +1,6 @@
{
"ProjectSettings": {
"Name": "cpl-test",
"Name": "database",
"Version": {
"Major": "0",
"Minor": "0",
@ -16,18 +16,20 @@
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"sh_cpl==2021.4.1.post13"
"sh_cpl==2021.4.2.dev1"
],
"PythonVersion": ">=3.9.2",
"PythonPath": "/home/sven/Nextcloud_Sven/Schreibtisch/git_sh-edraft_de/sh_common_py_lib/src/tests/custom/general/../../../../cpl-env/bin/python3.9",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"SourcePath": "src",
"OutputPath": "dist",
"Main": "main",
"EntryPoint": "cpl-test",
"IncludePackageData": true,
"EntryPoint": "database",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",

View File

@ -0,0 +1,36 @@
from typing import Optional
from cpl.application import ApplicationABC
from cpl.configuration import ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceProviderABC
from cpl.logging import LoggerABC
from model.user_repo_abc import UserRepoABC
from model.user_repo import UserRepo
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
self._logger: Optional[LoggerABC] = None
def configure(self):
self._logger = self._services.get_service(LoggerABC)
def main(self):
self._logger.header(f'{self._configuration.environment.application_name}:')
self._logger.debug(__name__, f'Host: {self._configuration.environment.host_name}')
self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}')
self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}')
user_repo: UserRepo = self._services.get_service(UserRepoABC)
user_repo.add_test_user()
Console.write_line('Users:')
for user in user_repo.get_users():
Console.write_line(user.Id, user.Name, user.City_Id, user.City.Id, user.City.Name, user.City.ZIP)
Console.write_line('Cities:')
for city in user_repo.get_cities():
Console.write_line(city.Id, city.Name, city.ZIP)

View File

@ -0,0 +1,14 @@
from cpl.application import ApplicationBuilder
from application import Application
from startup import Startup
def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app_builder.build().run()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,14 @@
from sqlalchemy import Column, Integer, String
from cpl.database import DatabaseModel
class CityModel(DatabaseModel):
__tablename__ = 'Cities'
Id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
Name = Column(String(64), nullable=False)
ZIP = Column(String(5), nullable=False)
def __init__(self, name: str, zip_code: str):
self.Name = name
self.ZIP = zip_code

View File

@ -0,0 +1,8 @@
from cpl.database import DatabaseSettings
from cpl.database.context import DatabaseContext
class DBContext(DatabaseContext):
def __init__(self, db_settings: DatabaseSettings):
DatabaseContext.__init__(self, db_settings)

View File

@ -0,0 +1,18 @@
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from cpl.database import DatabaseModel
from .city_model import CityModel
class UserModel(DatabaseModel):
__tablename__ = 'Users'
Id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
Name = Column(String(64), nullable=False)
City_Id = Column(Integer, ForeignKey('Cities.Id'), nullable=False)
City = relationship("CityModel")
def __init__(self, name: str, city: CityModel):
self.Name = name
self.City_Id = city.Id
self.City = city

View File

@ -0,0 +1,29 @@
from cpl.database.context import DatabaseContextABC
from .city_model import CityModel
from .user_model import UserModel
from .user_repo_abc import UserRepoABC
class UserRepo(UserRepoABC):
def __init__(self, db_context: DatabaseContextABC):
UserRepoABC.__init__(self)
self._session = db_context.session
self._user_query = db_context.session.query(UserModel)
def create(self): pass
def add_test_user(self):
city = CityModel('Haren', '49733')
city2 = CityModel('Meppen', '49716')
self._session.add(city2)
user = UserModel('TestUser', city)
self._session.add(user)
self._session.commit()
def get_users(self) -> list[UserModel]:
return self._session.query(UserModel).all()
def get_cities(self) -> list[CityModel]:
return self._session.query(CityModel).all()

View File

@ -0,0 +1,12 @@
from abc import ABC, abstractmethod
from .user_model import UserModel
class UserRepoABC(ABC):
@abstractmethod
def __init__(self): pass
@abstractmethod
def get_users(self) -> list[UserModel]: pass

View File

@ -0,0 +1,39 @@
from cpl.application import StartupABC
from cpl.configuration import ConfigurationABC
from cpl.database import DatabaseSettings
from cpl.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl.logging import LoggerABC, Logger
from model.db_context import DBContext
from model.user_repo import UserRepo
from model.user_repo_abc import UserRepoABC
class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self)
self._configuration = config
self._environment = self._configuration.environment
self._services = services
def configure_configuration(self) -> ConfigurationABC:
self._configuration.add_environment_variables('PYTHON_')
self._configuration.add_environment_variables('CPL_')
self._configuration.add_console_arguments()
self._configuration.add_json_file(f'appsettings.json')
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.environment_name}.json')
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True)
return self._configuration
def configure_services(self) -> ServiceProviderABC:
# Create and connect to database
db_settings: DatabaseSettings = self._configuration.get_configuration(DatabaseSettings)
self._services.add_db_context(DBContext, db_settings)
self._services.add_singleton(UserRepoABC, UserRepo)
self._services.add_singleton(LoggerABC, Logger)
return self._services.build_service_provider()

View File

@ -2,19 +2,19 @@ import time
from typing import Optional
from cpl.application.application_abc import ApplicationABC
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email import EMail
from cpl.mailing.email_client_abc import EMailClientABC
from tests.custom.general.test_service import TestService
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, runtime, services)
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
self._logger: Optional[LoggerABC] = None
self._mailer: Optional[EMailClientABC] = None
@ -23,20 +23,11 @@ class Application(ApplicationABC):
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(' sven.heidemann@sh-edraft.de')
mail.add_receiver('sven.heidemann@sh-edraft.de')
mail.subject = f'Test - {self._configuration.environment.host_name}'
mail.body = 'Dies ist ein Test :D'
self._mailer.send_mail(mail)
def test_console(self):
self._logger.debug(__name__, 'Started console_old model')
Console.write_line('Hello World')
Console.write('\nName: ')
Console.write_line(' Hello', Console.read_line())
Console.clear()
Console.write_at(5, 5, 'at 5, 5')
Console.write_at(10, 10, 'at 10, 10')
@staticmethod
def _wait(time_ms: int):
time.sleep(time_ms)
@ -50,6 +41,7 @@ class Application(ApplicationABC):
self._logger.debug(__name__, f'Host: {self._configuration.environment.host_name}')
self._logger.debug(__name__, f'Environment: {self._configuration.environment.environment_name}')
self._logger.debug(__name__, f'Customer: {self._configuration.environment.customer}')
Console.spinner('Test', self._wait, 20, spinner_foreground_color='red')
Console.spinner('Test', self._wait, 2, spinner_foreground_color='red')
test: TestService = self._services.get_service(TestService)
test.run()
# self.test_send_mail()
# self.test_console()

View File

@ -1,23 +1,20 @@
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.application.startup_abc import StartupABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.database.context.database_context import DatabaseContext
from cpl.database.database_settings import DatabaseSettings
from cpl.dependency_injection.service_collection_abc import ServiceCollectionABC
from cpl.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl.logging.logger_service import Logger
from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email_client_service import EMailClient
from cpl.mailing.email_client_abc import EMailClientABC
from cpl.utils.credential_manager import CredentialManager
from tests.custom.general.test_service import TestService
class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, runtime: ApplicationRuntimeABC, services: ServiceProviderABC):
def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self)
self._configuration = config
self._application_runtime = runtime
self._services = services
def configure_configuration(self) -> ConfigurationABC:
@ -31,13 +28,8 @@ class Startup(StartupABC):
return self._configuration
def configure_services(self) -> ServiceProviderABC:
# Create and connect to database
db_settings: DatabaseSettings = self._configuration.get_configuration(DatabaseSettings)
self._services.add_db_context(DatabaseContext)
db: DatabaseContext = self._services.get_db_context()
db.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials))
self._services.add_singleton(LoggerABC, Logger)
self._services.add_singleton(EMailClientABC, EMailClient)
self._services.add_singleton(TestService)
return self._services
return self._services.build_service_provider()

View File

@ -0,0 +1,15 @@
from abc import ABC
from cpl.console.console import Console
from cpl.dependency_injection import ServiceProviderABC
class TestService(ABC):
def __init__(self, provider: ServiceProviderABC):
ABC.__init__(self)
self._provider = provider
def run(self):
Console.write_line('Hello World!', self._provider)

View File

View File

View File

@ -0,0 +1,41 @@
{
"ProjectSettings": {
"Name": "simple-app",
"Version": {
"Major": "0",
"Minor": "0",
"Micro": "0"
},
"Author": "",
"AuthorEmail": "",
"Description": "",
"LongDescription": "",
"URL": "",
"CopyrightDate": "",
"CopyrightName": "",
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"sh_cpl==2021.4.2"
],
"PythonVersion": ">=3.9.2",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"SourcePath": "src",
"OutputPath": "dist",
"Main": "main",
"EntryPoint": "simple-app",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {}
}
}

View File

@ -0,0 +1,16 @@
from cpl.application import ApplicationABC
from cpl.configuration import ConfigurationABC
from cpl.console import Console
from cpl.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass
def main(self):
Console.write_line('Hello World')

View File

@ -0,0 +1,12 @@
from cpl.application import ApplicationBuilder
from application import Application
def main():
app_builder = ApplicationBuilder(Application)
app_builder.build().run()
if __name__ == '__main__':
main()

View File

@ -0,0 +1 @@
# imports:

View File

@ -0,0 +1,41 @@
{
"ProjectSettings": {
"Name": "simple-console",
"Version": {
"Major": "0",
"Minor": "0",
"Micro": "0"
},
"Author": "",
"AuthorEmail": "",
"Description": "",
"LongDescription": "",
"URL": "",
"CopyrightDate": "",
"CopyrightName": "",
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"sh_cpl==2021.4.2"
],
"PythonVersion": ">=3.9.2",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"SourcePath": "src",
"OutputPath": "dist",
"Main": "main",
"EntryPoint": "simple-console",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {}
}
}

View File

@ -0,0 +1,9 @@
from cpl.console import Console
def main():
Console.write_line('Hello World')
if __name__ == '__main__':
main()

View File

@ -0,0 +1 @@
# imports:

View File

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