2021.4.1 #11

Merged
edraft merged 172 commits from 2021.04.01 into 2021.04 2021-03-21 20:04:24 +01:00
205 changed files with 2207 additions and 1010 deletions
Showing only changes of commit 68c136a16f - Show all commits

1
.gitignore vendored
View File

@ -131,3 +131,4 @@ dmypy.json
# IDE # IDE
.vscode/ .vscode/
/src_old/

View File

@ -4,15 +4,16 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/dist" /> <excludeFolder url="file://$MODULE_DIR$/dist" />
<excludeFolder url="file://$MODULE_DIR$/src/tests/logs" /> <excludeFolder url="file://$MODULE_DIR$/src_old/tests/logs" />
<excludeFolder url="file://$MODULE_DIR$/src/tests_dev/logs" /> <excludeFolder url="file://$MODULE_DIR$/src_old/tests_dev/logs" />
<excludeFolder url="file://$MODULE_DIR$/src/sh_edraft.egg-info" /> <excludeFolder url="file://$MODULE_DIR$/src_old/sh_edraft.egg-info" />
<excludeFolder url="file://$MODULE_DIR$/src/dist" /> <excludeFolder url="file://$MODULE_DIR$/src_old/dist" />
<excludeFolder url="file://$MODULE_DIR$/src/build" /> <excludeFolder url="file://$MODULE_DIR$/src_old/build" />
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/src/tests/old" /> <excludeFolder url="file://$MODULE_DIR$/src_old/tests/old" />
<excludeFolder url="file://$MODULE_DIR$/.vscode" /> <excludeFolder url="file://$MODULE_DIR$/.vscode" />
<excludeFolder url="file://$MODULE_DIR$/build_test" /> <excludeFolder url="file://$MODULE_DIR$/build_test" />
<excludeFolder url="file://$MODULE_DIR$/src_old" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />

View File

@ -22,30 +22,211 @@
<select /> <select />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="7e2256bc-a6b8-4880-83a6-8b0e3372d0a4" name="Default Changelist" comment="Removed unused packages"> <list default="true" id="7e2256bc-a6b8-4880-83a6-8b0e3372d0a4" name="Default Changelist" comment="Updated requirements">
<change afterPath="$PROJECT_DIR$/src/tests/publish_test/__init__.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/cpl/application/application_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/tests/publish_test/publisher_test.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/cpl/application/application_host_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/tests/setup.py" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/cpl/application/application_runtime_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/application/startup_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/configuration/configuration.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/configuration/configuration_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/configuration/configuration_model_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/console/console.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/environment/environment_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/environment/hosting_environment.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/logging/logger.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/logging/logger_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/logging/logging_settings.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/mailing/email_client_abc.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/mailing/email_client_settings.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl/time/time_format_settings.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/cpl_cli/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/tests/Application.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/tests/Startup.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/tests/cpl.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/tests/main.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/configuration/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/configuration/model/configuration_variable_name.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/console/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/console/model/background_color.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/console/model/foreground_color.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/connection/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/connection/base/database_connection_base.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/connection/database_connection.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/context/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/context/base/database_context_base.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/context/database_context.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/model/database_settings.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/model/database_settings_name.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/model/dbmodel.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/environment/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/environment/model/environment_name.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/application_host.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/application_runtime.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/model/logging_level.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/model/logging_settings_name.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/email_client.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/model/email.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/model/email_client_settings_name.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/providing/base/service_provider_base.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/providing/model/provide_state.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/providing/service_provider.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/time/model/time_format_settings_names.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/utils/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/sh_edraft/utils/credential_manager.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests/appsettings.edrafts-lapi.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests/appsettings.edrafts-pc.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests/publish_test/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests/service_test/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests/time_test/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests/utils_test/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests_dev/app.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests_dev/appsettings.development.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src_old/tests_dev/appsettings.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/sh_common_py_lib.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/sh_common_py_lib.iml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/sh_common_py_lib.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/sh_common_py_lib.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/build/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/build/app.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/MANIFEST.in" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/MANIFEST.in" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/publish/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/publish/app.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/build.json" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/setup.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/setup.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/base/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/base/publisher_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/base/publisher_base.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/model/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/command/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/model/publish_settings_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/model/publish_settings_model.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/command/base/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/model/publish_settings_name.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/model/publish_settings_name.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/command/base/command_base.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/model/template.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/model/template.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/model/template_enum.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/model/template_enum.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/cli.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/publisher.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/sh_edraft/publish/publisher.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/build/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/build/app.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/build/build.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/help.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/new.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/publish/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/publish/app.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/publish/publish.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/version.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/app/__init__.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/app/build.json" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/app/main.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/app/program.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/base/base.txt" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/base/service_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/class/class.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/configmodel/model.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/enum/enum.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/templates/service/service.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/interpreter/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/cli/interpreter/interpreter.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/coding/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/coding/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/coding/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/coding/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/coding/model/version.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/coding/model/version.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/coding/model/version_enum.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/coding/model/version_enum.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/configuration/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/configuration/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/configuration/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/configuration/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/configuration/base/configuration_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/configuration/base/configuration_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/configuration/base/configuration_model_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/configuration/base/configuration_model_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/configuration/configuration.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/configuration/configuration.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/configuration/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/configuration/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/configuration/model/configuration_variable_name.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/configuration/configuration_variable_name.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/console/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/console/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/console/console.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/console/console.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/console/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/console/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/console/model/background_color.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/console/background_color.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/console/model/foreground_color.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/console/foreground_color.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/connection/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/connection/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/connection/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/connection/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/connection/base/database_connection_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/connection/database_connection_abc.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/connection/database_connection.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/connection/database_connection.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/context/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/context/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/context/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/context/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/context/base/database_context_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/context/database_context_abc.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/context/database_context.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/context/database_context.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/database/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/model/database_settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/database_settings.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/model/database_settings_name.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/database_settings_name.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/database/model/dbmodel.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/database/database_model.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/environment/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/environment/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/environment/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/environment/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/environment/base/environment_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/environment/base/environment_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/environment/hosting_environment.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/environment/hosting_environment.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/environment/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/environment/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/environment/model/environment_name.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/environment/environment_name.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/application_host.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/application/application_host.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/application_runtime.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/application/application_runtime.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/base/application_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/base/application_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/base/application_host_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/base/application_host_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/base/application_runtime_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/base/application_runtime_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/hosting/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/hosting/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/logging/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/base/logger_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/base/logger_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/logger.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/logger.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/model/logging_level.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/logging/logging_level.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/model/logging_settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/logging/model/logging_settings.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/logging/model/logging_settings_name.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/logging/logging_settings_name.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/mailing/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/base/email_client_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/base/email_client_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/email_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/mailing/email_client.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/model/email.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/mailing/email.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/model/email_client_settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/mailing/model/email_client_settings.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/mailing/model/email_client_settings_name.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/mailing/email_client_settings_name.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publish/base/publisher_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/publish/base/publisher_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publish/model/publish_settings_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/publish/model/publish_settings_model.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publish/model/publish_settings_name.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/publish/model/publish_settings_name.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publish/model/template.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/publish/model/template.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publish/model/template_enum.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/publish/model/template_enum.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publish/publisher.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/publish/publisher.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/base/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/publishing/model/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/base/service_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/dependency_injection/service_abc.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/providing/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/providing/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/providing/base/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/providing/base/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/providing/base/service_provider_base.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/dependency_injection/service_provider_base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/providing/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/service/providing/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/providing/model/provide_state.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/dependency_injection/provide_state.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/service/providing/service_provider.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/dependency_injection/service_provider.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/time/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/time/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/time/model/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/time/model/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/time/model/time_format_settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/sh_edraft/time/model/time_format_settings.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/time/model/time_format_settings_names.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/time/time_format_settings_names.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/utils/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/utils/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/sh_edraft/utils/credential_manager.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/utils/credential_manager.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/tests/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/appsettings.edrafts-lapi.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/appsettings.edrafts-lapi.json" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/tests/appsettings.edrafts-lapi.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/appsettings.edrafts-lapi.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/appsettings.edrafts-pc.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/appsettings.edrafts-pc.json" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/tests/appsettings.edrafts-pc.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/appsettings.edrafts-pc.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/build.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/build.json" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/tests/appsettings.testing.json" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/appsettings.testing.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/service_test/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/service_test/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/tests/build.json" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/build.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/time_test/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/time_test/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/tests/publish_test/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/utils_test/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/utils_test/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/tests/publish_test/publisher_test.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/publish_test/publisher_test.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/service_test/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/application/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/service_test/provider_test.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/service_test/provider_test.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/setup.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/setup.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/time_test/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/dependency_injection/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/time_test/time_format_settings_test.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/time_test/time_format_settings_test.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/utils_test/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/cpl/time/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests/utils_test/credential_manager_test.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/utils_test/credential_manager_test.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests_dev/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/appsettings.development.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/tests/appsettings.development.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/appsettings.edrafts-lapi.json" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests_dev/appsettings.edrafts-lapi.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/appsettings.edrafts-pc.json" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests_dev/appsettings.edrafts-pc.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/appsettings.json" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/appsettings.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/db/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/db/city.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/db/user.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/db/user_repo.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/db/user_repo_base.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests_dev/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tests_dev/program.py" beforeDir="false" afterPath="$PROJECT_DIR$/src_old/tests_dev/program.py" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -55,8 +236,8 @@
<component name="FileTemplateManagerImpl"> <component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES"> <option name="RECENT_TEMPLATES">
<list> <list>
<option value="Python Script" />
<option value="Python Unit Test" /> <option value="Python Unit Test" />
<option value="Python Script" />
</list> </list>
</option> </option>
</component> </component>
@ -69,13 +250,24 @@
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY"> <option name="RECENT_BRANCH_BY_REPOSITORY">
<map> <map>
<entry key="$PROJECT_DIR$" value="2020.12" /> <entry key="$PROJECT_DIR$" value="master" />
</map> </map>
</option> </option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
<option name="RESET_MODE" value="HARD" /> <option name="RESET_MODE" value="HARD" />
<option name="UPDATE_TYPE" value="REBASE" /> <option name="UPDATE_TYPE" value="REBASE" />
</component> </component>
<component name="GitSEFilterConfiguration">
<file-type-list>
<filtered-out-file-type name="LOCAL_BRANCH" />
<filtered-out-file-type name="REMOTE_BRANCH" />
<filtered-out-file-type name="TAG" />
<filtered-out-file-type name="COMMIT_BY_MESSAGE" />
</file-type-list>
</component>
<component name="HighlightingSettingsPerFile">
<setting file="file:///usr/local/lib/python3.9/dist-packages/sqlalchemy/engine/__init__.py" root0="FORCE_HIGHLIGHTING" />
</component>
<component name="ProjectId" id="1kYeNqJzjIXigSYYCzg4D16FL1E" /> <component name="ProjectId" id="1kYeNqJzjIXigSYYCzg4D16FL1E" />
<component name="ProjectViewState"> <component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
@ -84,26 +276,29 @@
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/src/tests" /> <property name="last_opened_file_path" value="$PROJECT_DIR$/src/cpl/dependency_injection" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" /> <property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component> </component>
<component name="ReaderModeSettings">
<option name="enabled" value="false" />
</component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src/cpl/dependency_injection" />
<recent name="$PROJECT_DIR$/src/cpl/application" />
<recent name="$PROJECT_DIR$/src/cpl/common/application" />
<recent name="$PROJECT_DIR$/src/cpl" />
<recent name="$PROJECT_DIR$/src/tests" /> <recent name="$PROJECT_DIR$/src/tests" />
<recent name="$PROJECT_DIR$/src/tests_dev" />
<recent name="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/database" />
<recent name="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/publish" />
<recent name="$PROJECT_DIR$/src" />
</key> </key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src/tests" /> <recent name="$PROJECT_DIR$/src/cpl" />
<recent name="$PROJECT_DIR$/src/tests/publish_test" /> <recent name="$PROJECT_DIR$/src/cpl/database/connection" />
<recent name="$PROJECT_DIR$/src/tests/old" /> <recent name="$PROJECT_DIR$/src/cpl/database/context" />
<recent name="$PROJECT_DIR$/src/sh_edraft/cli/cpl_cli/commands/build" /> <recent name="$PROJECT_DIR$/src/cpl/database" />
<recent name="$PROJECT_DIR$/src" /> <recent name="$PROJECT_DIR$/src/cpl/common/application" />
</key> </key>
</component> </component>
<component name="RunManager" selected="Python tests.Unittests"> <component name="RunManager" selected="Python.main">
<configuration name="cli build" type="PythonConfigurationType" factoryName="Python"> <configuration name="cli build" type="PythonConfigurationType" factoryName="Python">
<module name="sh_common_py_lib" /> <module name="sh_common_py_lib" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
@ -387,11 +582,11 @@
<env name="PYTHON_ENVIRONMENT" value="development" /> <env name="PYTHON_ENVIRONMENT" value="development" />
</envs> </envs>
<option name="SDK_HOME" value="" /> <option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/src/tests_dev" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/src/tests" />
<option name="IS_MODULE_SDK" value="true" /> <option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/tests_dev/main.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/tests/main.py" />
<option name="PARAMETERS" value="--customer=sh-edraft.de" /> <option name="PARAMETERS" value="--customer=sh-edraft.de" />
<option name="SHOW_COMMAND_LINE" value="false" /> <option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" /> <option name="EMULATE_TERMINAL" value="true" />
@ -408,7 +603,7 @@
<env name="CPL_ENVIRONMENT" value="testing" /> <env name="CPL_ENVIRONMENT" value="testing" />
</envs> </envs>
<option name="SDK_HOME" value="" /> <option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/src/tests" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/src_old/tests" />
<option name="IS_MODULE_SDK" value="true" /> <option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
@ -456,6 +651,7 @@
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Python tests.Unittests" /> <item itemvalue="Python tests.Unittests" />
<item itemvalue="Python tests.Unittests" />
</list> </list>
</recent_temporary> </recent_temporary>
</component> </component>
@ -468,13 +664,6 @@
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1605881914521</updated> <updated>1605881914521</updated>
</task> </task>
<task id="LOCAL-00031" summary="Improved database module structure">
<created>1607285697331</created>
<option name="number" value="00031" />
<option name="presentableId" value="LOCAL-00031" />
<option name="project" value="LOCAL" />
<updated>1607285697331</updated>
</task>
<task id="LOCAL-00032" summary="Improved database module structure"> <task id="LOCAL-00032" summary="Improved database module structure">
<created>1607620265254</created> <created>1607620265254</created>
<option name="number" value="00032" /> <option name="number" value="00032" />
@ -811,7 +1000,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1611431001649</updated> <updated>1611431001649</updated>
</task> </task>
<option name="localTasksCounter" value="80" /> <task id="LOCAL-00080" summary="Removed publish package">
<created>1614372713621</created>
<option name="number" value="00080" />
<option name="presentableId" value="LOCAL-00080" />
<option name="project" value="LOCAL" />
<updated>1614372713621</updated>
</task>
<option name="localTasksCounter" value="81" />
<servers /> <servers />
</component> </component>
<component name="Vcs.Log.Tabs.Properties"> <component name="Vcs.Log.Tabs.Properties">
@ -827,7 +1023,6 @@
<option name="oldMeFiltersMigrated" value="true" /> <option name="oldMeFiltersMigrated" value="true" />
</component> </component>
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<MESSAGE value="Added build command to cli" />
<MESSAGE value="Improved publish process" /> <MESSAGE value="Improved publish process" />
<MESSAGE value="Added publish command to cli" /> <MESSAGE value="Added publish command to cli" />
<MESSAGE value="Added imports to cli module" /> <MESSAGE value="Added imports to cli module" />
@ -852,13 +1047,14 @@
<MESSAGE value="Improved tests" /> <MESSAGE value="Improved tests" />
<MESSAGE value="Bugfixes and improved tests" /> <MESSAGE value="Bugfixes and improved tests" />
<MESSAGE value="Removed unused packages" /> <MESSAGE value="Removed unused packages" />
<option name="LAST_COMMIT_MESSAGE" value="Removed unused packages" /> <MESSAGE value="Removed publish package" />
<option name="LAST_COMMIT_MESSAGE" value="Removed publish package" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager> <breakpoint-manager>
<breakpoints> <breakpoints>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line"> <line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/src/tests/publish_test/publisher_test.py</url> <url>file://$PROJECT_DIR$/src_old/tests/publish_test/publisher_test.py</url>
<line>50</line> <line>50</line>
<option name="timeStamp" value="3" /> <option name="timeStamp" value="3" />
</line-breakpoint> </line-breakpoint>

View File

@ -1,66 +0,0 @@
{
"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": "../build/logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "INFO",
"FileLogLevel": "TRACE"
},
"PublishSettings": {
"SourcePath": "./",
"DistPath": "../build/dist",
"Templates": [
{
"TemplatePath": "../publish_templates/all_template.txt",
"Name": "all",
"Description": "",
"LongDescription": "",
"CopyrightDate": "2020",
"CopyrightName": "sh-edraft.de",
"LicenseName": "MIT",
"LicenseDescription": ", see LICENSE for more details.",
"Title": "",
"Author": "Sven Heidemann",
"Version": {
"Major": 2020,
"Minor": 12,
"Micro": 10
}
},
{
"TemplatePath": "../publish_templates/all_template.txt",
"Name": "sh_edraft",
"Description": "common python library",
"LongDescription": "Library to share common classes and models used at sh-edraft.de",
"CopyrightDate": "2020",
"CopyrightName": "sh-edraft.de",
"LicenseName": "MIT",
"LicenseDescription": ", see LICENSE for more details.",
"Title": "",
"Author": "Sven Heidemann",
"Version": {
"Major": 2020,
"Minor": 12,
"Micro": 10
}
}
],
"IncludedFiles": [
"./MANIFEST.in",
"../LICENSE",
"../README.md",
"../requirements.txt",
"sh_edraft/cli/cpl_cli/templates"
],
"ExcludedFiles": [
"./tests",
"./tests_dev"
],
"TemplateEnding": "_template.txt"
}
}

View File

@ -0,0 +1,32 @@
from abc import ABC, abstractmethod
from typing import Type, Optional
from cpl.application.application_host_abc import ApplicationHostABC
from cpl.application.startup_abc import StartupABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_provider_base import ServiceProviderABC
class ApplicationABC(ABC):
@abstractmethod
def __init__(self):
self._startup: Optional[StartupABC] = None
self._app_host: Optional[ApplicationHostABC] = None
self._services: Optional[ServiceProviderABC] = None
self._configuration: Optional[ConfigurationABC] = None
def use_startup(self, startup: Type[StartupABC]):
self._startup = startup()
def build(self):
if self._startup is None:
print('Startup is empty')
exit()
self._app_host = self._startup.create_application_host()
self._configuration = self._startup.create_configuration()
self._services = self._startup.create_services()
@abstractmethod
def run(self): pass

View File

@ -0,0 +1,42 @@
import atexit
from datetime import datetime
from cpl.application.application_host_abc import ApplicationHostABC
from cpl.application.application_runtime import ApplicationRuntime
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration import Configuration
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.console.console import Console
from cpl.dependency_injection.service_provider import ServiceProvider
from cpl.dependency_injection.service_provider_base import ServiceProviderABC
class ApplicationHost(ApplicationHostABC):
def __init__(self):
ApplicationHostABC.__init__(self)
# Init
self._config = Configuration()
self._app_runtime = ApplicationRuntime(self._config)
self._services = ServiceProvider(self._app_runtime)
# Set vars
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
atexit.register(Console.close)
@property
def configuration(self) -> ConfigurationABC:
return self._config
@property
def application_runtime(self) -> ApplicationRuntimeABC:
return self._app_runtime
@property
def services(self) -> ServiceProviderABC:
return self._services
def create(self): pass

View File

@ -0,0 +1,23 @@
from abc import ABC, abstractmethod
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_provider_base import ServiceProviderABC
class ApplicationHostABC(ABC):
@abstractmethod
def __init__(self): pass
@property
@abstractmethod
def configuration(self) -> ConfigurationABC: pass
@property
@abstractmethod
def application_runtime(self) -> ApplicationRuntimeABC: pass
@property
@abstractmethod
def services(self) -> ServiceProviderABC: pass

View File

@ -0,0 +1,38 @@
from datetime import datetime
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_abc import ConfigurationABC
class ApplicationRuntime(ApplicationRuntimeABC):
def __init__(self, config: ConfigurationABC):
ApplicationRuntimeABC.__init__(self)
self._app_configuration = config
self._start_time: datetime = datetime.now()
self._end_time: datetime = datetime.now()
@property
def configuration(self) -> ConfigurationABC:
return self._app_configuration
@property
def start_time(self) -> datetime:
return self._start_time
@start_time.setter
def start_time(self, start_time: datetime):
self._start_time = 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()

View File

@ -0,0 +1,34 @@
from abc import ABC, abstractmethod
from datetime import datetime
from cpl.configuration.configuration_abc import ConfigurationABC
class ApplicationRuntimeABC(ABC):
@abstractmethod
def __init__(self): pass
@property
@abstractmethod
def configuration(self) -> ConfigurationABC: 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

View File

@ -0,0 +1,20 @@
from abc import ABC, abstractmethod
from cpl.application.application_host_abc import ApplicationHostABC
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.dependency_injection.service_provider_base import ServiceProviderABC
class StartupABC(ABC):
@abstractmethod
def __init__(self): pass
@abstractmethod
def create_application_host(self) -> ApplicationHostABC: pass
@abstractmethod
def create_configuration(self) -> ConfigurationABC: pass
@abstractmethod
def create_services(self) -> ServiceProviderABC: pass

View File

@ -0,0 +1,118 @@
import json
import os
import sys
from cpl.configuration.configuration_abc import ConfigurationABC
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.configuration.configuration_variable_name import ConfigurationVariableName
from cpl.console.console import Console
from cpl.console.foreground_color import ForegroundColor
from cpl.environment.hosting_environment import HostingEnvironment
from cpl.environment.environment_abc import EnvironmentABC
from cpl.environment.environment_name import EnvironmentName
class Configuration(ConfigurationABC):
def __init__(self):
ConfigurationABC.__init__(self)
self._hosting_environment = HostingEnvironment()
self._config: dict[type, ConfigurationModelABC] = {}
@property
def environment(self) -> EnvironmentABC:
return self._hosting_environment
@staticmethod
def _print_info(name: str, message: str):
Console.set_foreground_color(ForegroundColor.green)
Console.write_line(f'[{name}] {message}')
Console.set_foreground_color(ForegroundColor.default)
@staticmethod
def _print_warn(name: str, message: str):
Console.set_foreground_color(ForegroundColor.yellow)
Console.write_line(f'[{name}] {message}')
Console.set_foreground_color(ForegroundColor.default)
@staticmethod
def _print_error(name: str, message: str):
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(f'[{name}] {message}')
Console.set_foreground_color(ForegroundColor.default)
def _set_variable(self, name: str, value: str):
if name == ConfigurationVariableName.environment.value:
self._hosting_environment.environment_name = EnvironmentName(value)
elif name == ConfigurationVariableName.name.value:
self._hosting_environment.application_name = value
elif name == ConfigurationVariableName.customer.value:
self._hosting_environment.customer = value
def add_environment_variables(self, prefix: str):
for variable in ConfigurationVariableName.to_list():
var_name = f'{prefix}{variable}'
if var_name in [key.upper() for key in os.environ.keys()]:
self._set_variable(variable, os.environ[var_name])
def add_argument_variables(self):
for arg in sys.argv[1:]:
try:
argument = arg.split('--')[1].split('=')[0].upper()
value = arg.split('=')[1]
if argument not in ConfigurationVariableName.to_list():
raise Exception(f'Invalid argument name: {argument}')
self._set_variable(argument, value)
except Exception as e:
self._print_error(__name__, f'Invalid argument: {arg} -> {e}')
exit()
def add_json_file(self, name: str, optional: bool = None):
if self._hosting_environment.content_root_path.endswith('/') and not name.startswith('/'):
file_path = f'{self._hosting_environment.content_root_path}{name}'
else:
file_path = f'{self._hosting_environment.content_root_path}/{name}'
if not os.path.isfile(file_path):
if not optional:
self._print_error(__name__, f'File not found: {file_path}')
exit()
self._print_warn(__name__, f'Not Loaded config file: {file_path}')
return None
config_from_file = self._load_json_file(file_path)
for sub in ConfigurationModelABC.__subclasses__():
for key, value in config_from_file.items():
if sub.__name__ == key:
configuration = sub()
configuration.from_dict(value)
self.add_configuration(sub, configuration)
def _load_json_file(self, file: str) -> dict:
try:
# open config file, create if not exists
with open(file, encoding='utf-8') as cfg:
# load json
json_cfg = json.load(cfg)
self._print_info(__name__, f'Loaded config file: {file}')
return json_cfg
except Exception as e:
self._print_error(__name__, f'Cannot load config file: {file}! -> {e}')
return {}
def add_configuration(self, key_type: type, value: ConfigurationModelABC):
self._config[key_type] = value
def get_configuration(self, search_type: type) -> ConfigurationModelABC:
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]

View File

@ -0,0 +1,31 @@
from abc import abstractmethod, ABC
from collections import Callable
from typing import Type
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.environment.environment_abc import EnvironmentABC
class ConfigurationABC(ABC):
@abstractmethod
def __init__(self): pass
@property
@abstractmethod
def environment(self) -> EnvironmentABC: pass
@abstractmethod
def add_environment_variables(self, prefix: str): pass
@abstractmethod
def add_argument_variables(self): pass
@abstractmethod
def add_json_file(self, name: str, optional: bool = None): pass
@abstractmethod
def add_configuration(self, key_type: type, value: object): pass
@abstractmethod
def get_configuration(self, search_type: Type[ConfigurationModelABC]) -> Callable[ConfigurationModelABC]: pass

View File

@ -1,10 +1,10 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
class $Name(ABC): class ConfigurationModelABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): pass def __init__(self): pass
@abstractmethod @abstractmethod
def create(self): pass def from_dict(self, settings: dict): pass

205
src/cpl/console/console.py Normal file
View File

@ -0,0 +1,205 @@
import os
from typing import Union, Optional
import pyfiglet
from tabulate import tabulate
from termcolor import colored
from cpl.console.background_color import BackgroundColor
from cpl.console.foreground_color import ForegroundColor
class Console:
_is_first_write = True
_background_color: BackgroundColor = BackgroundColor.default
_foreground_color: ForegroundColor = ForegroundColor.default
_x: Optional[int] = None
_y: Optional[int] = None
_disabled: bool = False
"""
Properties
"""
@classmethod
@property
def background_color(cls) -> str:
return str(cls._background_color.value)
@classmethod
@property
def foreground_color(cls) -> str:
return str(cls._foreground_color.value)
"""
Settings
"""
@classmethod
def set_background_color(cls, color: Union[BackgroundColor, str]):
if type(color) is str:
cls._background_color = BackgroundColor[color]
else:
cls._background_color = color
@classmethod
def set_foreground_color(cls, color: Union[ForegroundColor, str]):
if type(color) is str:
cls._foreground_color = ForegroundColor[color]
else:
cls._foreground_color = color
@classmethod
def reset_cursor_position(cls):
cls._x = None
cls._y = None
@classmethod
def set_cursor_position(cls, x: int, y: int):
cls._x = x
cls._y = y
"""
Useful protected methods
"""
@classmethod
def _output(cls, string: str, x: int = None, y: int = None, end='\n'):
if cls._is_first_write:
cls._is_first_write = False
args = []
colored_args = []
if x is not None and y is not None:
args.append(f'\033[{x};{y}H')
elif cls._x is not None and cls._y is not None:
args.append(f'\033[{cls._x};{cls._y}H')
colored_args.append(string)
if cls._foreground_color != ForegroundColor.default and cls._background_color == BackgroundColor.default:
colored_args.append(cls._foreground_color.value)
elif cls._foreground_color == ForegroundColor.default and cls._background_color != BackgroundColor.default:
colored_args.append(cls._background_color.value)
elif cls._foreground_color != ForegroundColor.default and cls._background_color != BackgroundColor.default:
colored_args.append(cls._foreground_color.value)
colored_args.append(cls._background_color.value)
args.append(colored(*colored_args))
print(*args, end=end)
"""
Useful public methods
"""
@classmethod
def banner(cls, string: str):
if cls._disabled:
return
ascii_banner = pyfiglet.figlet_format(string)
cls.write_line(ascii_banner)
@classmethod
def clear(cls):
os.system('cls' if os.name == 'nt' else 'clear')
@classmethod
def close(cls):
if cls._disabled:
return
Console.reset()
Console.write('\n\n\nPress any key to continue...')
Console.read_line()
exit()
@classmethod
def disable(cls):
cls._disabled = True
@classmethod
def error(cls, string: str, tb: str = None):
if cls._disabled:
return
cls.set_foreground_color('red')
if tb is not None:
cls.write_line(f'{string} -> {tb}')
else:
cls.write_line(string)
cls.set_foreground_color('default')
@classmethod
def enable(cls):
cls._disabled = False
@classmethod
def read(cls, output: str = None) -> str:
if output is not None:
cls.write(output)
return input()[0]
@classmethod
def read_line(cls, output: str = None) -> str:
if cls._disabled:
return ''
if output is not None:
cls.write(output)
return input()
@classmethod
def reset(cls):
cls._background_color = BackgroundColor.default
cls._foreground_color = ForegroundColor.default
@classmethod
def table(cls, header: list[str], values: list[list[str]]):
if cls._disabled:
return
table = tabulate(values, headers=header)
Console.write_line(table)
Console.write('\n')
@classmethod
def write(cls, *args):
if cls._disabled:
return
string = ' '.join(map(str, args))
cls._output(string, end='')
@classmethod
def write_at(cls, x: int, y: int, *args):
if cls._disabled:
return
string = ' '.join(map(str, args))
cls._output(string, x, y, end='')
@classmethod
def write_line(cls, *args):
if cls._disabled:
return
string = ' '.join(map(str, args))
if not cls._is_first_write:
cls._output('')
cls._output(string, end='')
@classmethod
def write_line_at(cls, x: int, y: int, *args):
if cls._disabled:
return
string = ' '.join(map(str, args))
if not cls._is_first_write:
cls._output('', end='')
cls._output(string, x, y, end='')

View File

View File

View File

@ -0,0 +1,58 @@
from typing import Optional
from sqlalchemy import engine, create_engine
from sqlalchemy.orm import Session, sessionmaker
from cpl.console.console import Console
from cpl.console.foreground_color import ForegroundColor
from cpl.database.connection.database_connection_abc import DatabaseConnectionABC
from cpl.database.database_settings import DatabaseSettings
class DatabaseConnection(DatabaseConnectionABC):
def __init__(self, database_settings: DatabaseSettings):
DatabaseConnectionABC.__init__(self)
self._db_settings = database_settings
self._engine: Optional[engine] = None
self._session: Optional[Session] = None
self._credentials: Optional[str] = None
@property
def engine(self) -> engine:
return self._engine
@property
def session(self) -> Session:
return self._session
def connect(self, connection_string: str):
try:
self._engine = create_engine(connection_string)
if self._db_settings.auth_plugin is not None:
self._engine = create_engine(connection_string, connect_args={'auth_plugin': self._db_settings.auth_plugin})
if self._db_settings.encoding is not None:
self._engine.encoding = self._db_settings.encoding
if self._db_settings.case_sensitive is not None:
self._engine.case_sensitive = self._db_settings.case_sensitive
if self._db_settings.echo is not None:
self._engine.echo = self._db_settings.echo
self._engine.connect()
db_session = sessionmaker(bind=self._engine)
self._session = db_session()
Console.set_foreground_color(ForegroundColor.green)
Console.write_line(f'[{__name__}] Connected to database')
Console.set_foreground_color(ForegroundColor.default)
except Exception as e:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(f'[{__name__}] Database connection failed -> {e}')
Console.set_foreground_color(ForegroundColor.default)
exit()

View File

@ -0,0 +1,21 @@
from abc import abstractmethod, ABC
from sqlalchemy import engine
from sqlalchemy.orm import Session
class DatabaseConnectionABC(ABC):
@abstractmethod
def __init__(self): pass
@property
@abstractmethod
def engine(self) -> engine: pass
@property
@abstractmethod
def session(self) -> Session: pass
@abstractmethod
def connect(self, connection_string: str): pass

View File

View File

@ -0,0 +1,50 @@
from sqlalchemy import engine, Table
from sqlalchemy.orm import Session
from cpl.console.console import Console
from cpl.console.foreground_color import ForegroundColor
from cpl.database.connection.database_connection import DatabaseConnection
from cpl.database.connection.database_connection_abc import DatabaseConnectionABC
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.database.database_settings import DatabaseSettings
from cpl.database.database_model import DatabaseModel
class DatabaseContext(DatabaseContextABC):
def __init__(self, database_settings: DatabaseSettings):
DatabaseContextABC.__init__(self)
self._db: DatabaseConnectionABC = DatabaseConnection(database_settings)
self._tables: list[Table] = []
@property
def engine(self) -> engine:
return self._db.engine
@property
def session(self) -> Session:
return self._db.session
def create(self):
pass
def connect(self, connection_string: str):
self._db.connect(connection_string)
self._create_tables()
def _create_tables(self):
try:
for subclass in DatabaseModel.__subclasses__():
self._tables.append(subclass.__table__)
DatabaseModel.metadata.drop_all(self._db.engine, self._tables)
DatabaseModel.metadata.create_all(self._db.engine, self._tables, checkfirst=True)
Console.set_foreground_color(ForegroundColor.green)
Console.write_line(f'[{__name__}] Created tables')
Console.set_foreground_color(ForegroundColor.default)
except Exception as e:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(f'[{__name__}] Creating tables failed -> {e}')
Console.set_foreground_color(ForegroundColor.default)
exit()

View File

@ -0,0 +1,21 @@
from abc import abstractmethod, ABC
from sqlalchemy import engine
from sqlalchemy.orm import Session
class DatabaseContextABC(ABC):
@property
@abstractmethod
def engine(self) -> engine: pass
@property
@abstractmethod
def session(self) -> Session: pass
@abstractmethod
def connect(self, connection_string: str): pass
@abstractmethod
def _create_tables(self): pass

View File

@ -0,0 +1,3 @@
from sqlalchemy.ext.declarative import declarative_base
DatabaseModel: declarative_base = declarative_base()

View File

@ -0,0 +1,90 @@
import traceback
from typing import Optional
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.console.console import Console
from cpl.console.foreground_color import ForegroundColor
from cpl.database.database_settings_name import DatabaseSettingsName
class DatabaseSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._auth_plugin: Optional[str] = None
self._connection_string: Optional[str] = None
self._credentials: Optional[str] = None
self._encoding: Optional[str] = None
self._case_sensitive: Optional[bool] = None
self._echo: Optional[bool] = None
@property
def auth_plugin(self) -> str:
return self._auth_plugin
@auth_plugin.setter
def auth_plugin(self, auth_plugin: str):
self._auth_plugin = auth_plugin
@property
def connection_string(self) -> str:
return self._connection_string
@connection_string.setter
def connection_string(self, connection_string: str):
self._connection_string = connection_string
@property
def credentials(self) -> str:
return self._credentials
@credentials.setter
def credentials(self, credentials: str):
self._credentials = credentials
@property
def encoding(self) -> str:
return self._encoding
@encoding.setter
def encoding(self, encoding: str) -> None:
self._encoding = encoding
@property
def case_sensitive(self) -> bool:
return self._case_sensitive
@case_sensitive.setter
def case_sensitive(self, case_sensitive: bool) -> None:
self._case_sensitive = case_sensitive
@property
def echo(self) -> bool:
return self._echo
@echo.setter
def echo(self, echo: bool) -> None:
self._echo = echo
def from_dict(self, settings: dict):
try:
self._connection_string = settings[DatabaseSettingsName.connection_string.value]
self._credentials = settings[DatabaseSettingsName.credentials.value]
if DatabaseSettingsName.auth_plugin.value in settings:
self._auth_plugin = settings[DatabaseSettingsName.auth_plugin.value]
if DatabaseSettingsName.encoding.value in settings:
self._encoding = settings[DatabaseSettingsName.encoding.value]
if DatabaseSettingsName.case_sensitive.value in settings:
self._case_sensitive = bool(settings[DatabaseSettingsName.case_sensitive.value])
if DatabaseSettingsName.echo.value in settings:
self._echo = bool(settings[DatabaseSettingsName.echo.value])
except Exception as e:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')
Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')
Console.set_foreground_color(ForegroundColor.default)

View File

@ -0,0 +1,11 @@
from enum import Enum
class DatabaseSettingsName(Enum):
connection_string = 'ConnectionString'
credentials = 'Credentials'
encoding = 'Encoding'
case_sensitive = 'CaseSensitive'
echo = 'Echo'
auth_plugin = 'AuthPlugin'

View File

View File

@ -0,0 +1,7 @@
from abc import ABC, abstractmethod
class ServiceABC(ABC):
@abstractmethod
def __init__(self): pass

View File

@ -0,0 +1,95 @@
from abc import ABC
from collections import Callable
from inspect import signature, Parameter
from typing import Type, Optional, Union
from cpl.application.application_runtime_abc import ApplicationRuntimeABC
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.console.console import Console
from cpl.database.context.database_context_abc import DatabaseContextABC
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.dependency_injection.service_provider_base import ServiceProviderABC
from cpl.environment.environment_abc import EnvironmentABC
class ServiceProvider(ServiceProviderABC):
def __init__(self, app_runtime: ApplicationRuntimeABC):
ServiceProviderABC.__init__(self)
self._app_runtime: ApplicationRuntimeABC = app_runtime
self._database_context: Optional[DatabaseContextABC] = None
self._transient_services: dict[Type[ServiceABC], Type[ServiceABC]] = {}
self._scoped_services: dict[Type[ServiceABC], Type[ServiceABC]] = {}
self._singleton_services: dict[Type[ServiceABC], Callable[ServiceABC], ServiceABC] = {}
def _create_instance(self, service: Union[Callable[ServiceABC], ServiceABC]) -> Callable[ServiceABC]:
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, ApplicationRuntimeABC):
params.append(self._app_runtime)
elif issubclass(parameter.annotation, EnvironmentABC):
params.append(self._app_runtime.configuration.environment)
elif issubclass(parameter.annotation, DatabaseContextABC):
params.append(self._database_context)
elif issubclass(parameter.annotation, ConfigurationModelABC):
params.append(self._app_runtime.configuration.get_configuration(parameter.annotation))
else:
params.append(self.get_service(parameter.annotation))
return service(*params)
def add_db_context(self, db_context: Type[DatabaseContextABC]):
self._database_context = self._create_instance(db_context)
def get_db_context(self) -> Callable[DatabaseContextABC]:
return self._database_context
def add_transient(self, service_type: Type[ServiceABC], service: Type[ServiceABC]):
self._transient_services[service_type] = service
def add_scoped(self, service_type: Type[ServiceABC], service: Type[ServiceABC]):
self._scoped_services[service_type] = service
def add_singleton(self, service_type: Type[ServiceABC], service: Callable[ServiceABC]):
for known_service in self._singleton_services:
if type(known_service) == service_type:
raise Exception(f'Service with type {service_type} already exists')
self._singleton_services[service_type] = self._create_instance(service)
def get_service(self, instance_type: Type) -> Callable[ServiceABC]:
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

View File

@ -0,0 +1,33 @@
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
class ServiceProviderABC(ABC):
@abstractmethod
def __init__(self): pass
@abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC]): pass
@abstractmethod
def get_db_context(self) -> Callable[DatabaseContextABC]: pass
@abstractmethod
def add_transient(self, service_type: Type, service: Type): pass
@abstractmethod
def add_scoped(self, service_type: Type, service: Type): pass
@abstractmethod
def add_singleton(self, service_type: Type, service: Callable): pass
@abstractmethod
def get_service(self, instance_type: Type) -> Callable[ServiceABC]: pass
@abstractmethod
def remove_service(self, instance_type: type): pass

View File

View File

@ -0,0 +1,43 @@
from abc import ABC, abstractmethod
class EnvironmentABC(ABC):
@abstractmethod
def __init__(self): pass
@property
@abstractmethod
def environment_name(self) -> str: pass
@environment_name.setter
@abstractmethod
def environment_name(self, environment_name: str): pass
@property
@abstractmethod
def application_name(self) -> str: pass
@application_name.setter
@abstractmethod
def application_name(self, application_name: str): pass
@property
@abstractmethod
def customer(self) -> str: pass
@customer.setter
@abstractmethod
def customer(self, customer: str): pass
@property
@abstractmethod
def content_root_path(self) -> str: pass
@content_root_path.setter
@abstractmethod
def content_root_path(self, content_root_path: str): pass
@property
@abstractmethod
def host_name(self) -> str: pass

View File

@ -0,0 +1,52 @@
from socket import gethostname
from typing import Optional
from cpl.environment.environment_abc import EnvironmentABC
from cpl.environment.environment_name import EnvironmentName
class HostingEnvironment(EnvironmentABC):
def __init__(self, name: EnvironmentName = EnvironmentName.production, crp: str = './'):
EnvironmentABC.__init__(self)
self._environment_name: Optional[EnvironmentName] = name
self._app_name: Optional[str] = None
self._customer: Optional[str] = None
self._content_root_path: Optional[str] = crp
@property
def environment_name(self) -> str:
return str(self._environment_name.value)
@environment_name.setter
def environment_name(self, environment_name: str):
self._environment_name = EnvironmentName(environment_name)
@property
def application_name(self) -> str:
return self._app_name if self._app_name is not None else ''
@application_name.setter
def application_name(self, application_name: str):
self._app_name = application_name
@property
def customer(self) -> str:
return self._customer if self._customer is not None else ''
@customer.setter
def customer(self, customer: str):
self._customer = customer
@property
def content_root_path(self) -> str:
return self._content_root_path
@content_root_path.setter
def content_root_path(self, content_root_path: str):
self._content_root_path = content_root_path
@property
def host_name(self):
return gethostname()

View File

195
src/cpl/logging/logger.py Normal file
View File

@ -0,0 +1,195 @@
import datetime
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 import ForegroundColor
from cpl.logging.logger_abc import LoggerABC
from cpl.logging.logging_level import LoggingLevel
from cpl.logging.logging_settings import LoggingSettings
from cpl.time.time_format_settings import TimeFormatSettings
class Logger(LoggerABC):
def __init__(self, logging_settings: LoggingSettings, time_format: TimeFormatSettings, app_runtime: ApplicationRuntimeABC):
LoggerABC.__init__(self)
self._app_runtime = app_runtime
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)
)
self._path = self._log_settings.path
self._level = self._log_settings.level
self._console = self._log_settings.console
self.create()
def _get_datetime_now(self) -> str:
try:
return datetime.datetime.now().strftime(self._time_format_settings.date_time_format)
except Exception as e:
self.error(__name__, 'Cannot get time', ex=e)
def _get_date(self) -> str:
try:
return datetime.datetime.now().strftime(self._time_format_settings.date_format)
except Exception as e:
self.error(__name__, 'Cannot get date', ex=e)
def create(self) -> None:
""" path """
try:
# check if log file path exists
if not os.path.exists(self._path):
os.makedirs(self._path)
except Exception as e:
self._fatal_console(__name__, 'Cannot create log dir', ex=e)
""" create new log file """
try:
# open log file, create if not exists
path = f'{self._path}{self._log}'
f = open(path, "w+")
Console.write_line(f'[{__name__}]: Using log file: {path}')
f.close()
except Exception as e:
self._fatal_console(__name__, 'Cannot open log file', ex=e)
def _append_log(self, string):
try:
# open log file and append always
if not os.path.isdir(self._path):
self._fatal_console(__name__, 'Log directory not found')
with open(self._path + self._log, "a+", encoding="utf-8") as f:
f.write(string + '\n')
f.close()
except Exception as e:
self._fatal_console(__name__, f'Cannot append log file, message: {string}', ex=e)
def _get_string(self, name: str, level: LoggingLevel, message: str) -> str:
log_level = level.name
return f'<{self._get_datetime_now()}> [ {log_level} ] [ {name} ]: {message}'
def header(self, string: str):
# append log and print message
self._append_log(string)
Console.set_foreground_color(ForegroundColor.default)
Console.write_line(string)
Console.set_foreground_color(ForegroundColor.default)
def trace(self, name: str, message: str):
output = self._get_string(name, LoggingLevel.TRACE, message)
# check if message can be written to log
if self._level.value >= LoggingLevel.TRACE.value:
self._append_log(output)
# check if message can be shown in console
if self._console.value >= LoggingLevel.TRACE.value:
Console.set_foreground_color(ForegroundColor.green)
Console.write_line(output)
Console.set_foreground_color(ForegroundColor.default)
def debug(self, name: str, message: str):
output = self._get_string(name, LoggingLevel.DEBUG, message)
# check if message can be written to log
if self._level.value >= LoggingLevel.DEBUG.value:
self._append_log(output)
# check if message can be shown in console
if self._console.value >= LoggingLevel.DEBUG.value:
Console.set_foreground_color(ForegroundColor.green)
Console.write_line(output)
Console.set_foreground_color(ForegroundColor.default)
def info(self, name: str, message: str):
output = self._get_string(name, LoggingLevel.INFO, message)
# check if message can be written to log
if self._level.value >= LoggingLevel.INFO.value:
self._append_log(output)
# check if message can be shown in console
if self._console.value >= LoggingLevel.INFO.value:
Console.set_foreground_color(ForegroundColor.green)
Console.write_line(output)
Console.set_foreground_color(ForegroundColor.default)
def warn(self, name: str, message: str):
output = self._get_string(name, LoggingLevel.WARN, message)
# check if message can be written to log
if self._level.value >= LoggingLevel.WARN.value:
self._append_log(output)
# check if message can be shown in console
if self._console.value >= LoggingLevel.WARN.value:
Console.set_foreground_color(ForegroundColor.yellow)
Console.write_line(output)
Console.set_foreground_color(ForegroundColor.default)
def error(self, name: str, message: str, ex: Exception = None):
output = ''
if ex is not None:
tb = traceback.format_exc()
self.error(name, message)
output = self._get_string(name, LoggingLevel.ERROR, f'{ex} -> {tb}')
else:
output = self._get_string(name, LoggingLevel.ERROR, message)
# check if message can be written to log
if self._level.value >= LoggingLevel.ERROR.value:
self._append_log(output)
# check if message can be shown in console
if self._console.value >= LoggingLevel.ERROR.value:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(output)
Console.set_foreground_color(ForegroundColor.default)
def fatal(self, name: str, message: str, ex: Exception = None):
output = ''
if ex is not None:
tb = traceback.format_exc()
self.error(name, message)
output = self._get_string(name, LoggingLevel.FATAL, f'{ex} -> {tb}')
else:
output = self._get_string(name, LoggingLevel.FATAL, message)
# check if message can be written to log
if self._level.value >= LoggingLevel.FATAL.value:
self._append_log(output)
# check if message can be shown in console
if self._console.value >= LoggingLevel.FATAL.value:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(output)
Console.set_foreground_color(ForegroundColor.default)
exit()
def _fatal_console(self, name: str, message: str, ex: Exception = None):
output = ''
if ex is not None:
tb = traceback.format_exc()
self.error(name, message)
output = self._get_string(name, LoggingLevel.ERROR, f'{ex} -> {tb}')
else:
output = self._get_string(name, LoggingLevel.ERROR, message)
# check if message can be shown in console
if self._console.value >= LoggingLevel.FATAL.value:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(output)
Console.set_foreground_color(ForegroundColor.default)
exit()

View File

@ -0,0 +1,31 @@
from abc import abstractmethod
from cpl.dependency_injection.service_abc import ServiceABC
class LoggerABC(ServiceABC):
@abstractmethod
def __init__(self):
ServiceABC.__init__(self)
@abstractmethod
def header(self, string: str): pass
@abstractmethod
def trace(self, name: str, message: str): pass
@abstractmethod
def debug(self, name: str, message: str): pass
@abstractmethod
def info(self, name: str, message: str): pass
@abstractmethod
def warn(self, name: str, message: str): pass
@abstractmethod
def error(self, name: str, message: str, ex: Exception = None): pass
@abstractmethod
def fatal(self, name: str, message: str, ex: Exception = None): pass

View File

@ -0,0 +1,62 @@
import traceback
from typing import Optional
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.console.console import Console
from cpl.console.foreground_color import ForegroundColor
from cpl.logging.logging_level import LoggingLevel
from cpl.logging.logging_settings_name import LoggingSettingsName
class LoggingSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._path: Optional[str] = None
self._filename: Optional[str] = None
self._console: Optional[LoggingLevel] = None
self._level: Optional[LoggingLevel] = None
@property
def path(self) -> str:
return self._path
@path.setter
def path(self, path: str) -> None:
self._path = path
@property
def filename(self) -> str:
return self._filename
@filename.setter
def filename(self, filename: str) -> None:
self._filename = filename
@property
def console(self) -> LoggingLevel:
return self._console
@console.setter
def console(self, console: LoggingLevel) -> None:
self._console = console
@property
def level(self) -> LoggingLevel:
return self._level
@level.setter
def level(self, level: LoggingLevel) -> None:
self._level = level
def from_dict(self, settings: dict):
try:
self._path = settings[LoggingSettingsName.path.value]
self._filename = settings[LoggingSettingsName.filename.value]
self._console = LoggingLevel[settings[LoggingSettingsName.console_level.value]]
self._level = LoggingLevel[settings[LoggingSettingsName.file_level.value]]
except Exception as e:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')
Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')
Console.set_foreground_color(ForegroundColor.default)

View File

View File

@ -0,0 +1,70 @@
import ssl
from smtplib import SMTP
from typing import Optional
from cpl.environment.environment_abc import EnvironmentABC
from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email import EMail
from cpl.mailing.email_client_abc import EMailClientABC
from cpl.mailing.email_client_settings import EMailClientSettings
from cpl.utils.credential_manager import CredentialManager
class EMailClient(EMailClientABC):
def __init__(self, environment: EnvironmentABC, logger: LoggerABC, mail_settings: EMailClientSettings):
EMailClientABC.__init__(self)
self._environment = environment
self._mail_settings = mail_settings
self._logger = logger
self._server: Optional[SMTP] = None
self.create()
def create(self):
self._logger.trace(__name__, f'Started {__name__}.create')
self.connect()
self._logger.trace(__name__, f'Stopped {__name__}.create')
def connect(self):
self._logger.trace(__name__, f'Started {__name__}.connect')
try:
self._logger.debug(__name__, f'Try to connect to {self._mail_settings.host}:{self._mail_settings.port}')
self._server = SMTP(self._mail_settings.host, self._mail_settings.port)
self._logger.info(__name__, f'Connected to {self._mail_settings.host}:{self._mail_settings.port}')
self._logger.debug(__name__, 'Try to start tls')
self._server.starttls(context=ssl.create_default_context())
self._logger.info(__name__, 'Started tls')
except Exception as e:
self._logger.error(__name__, 'Cannot connect to mail server', e)
self._logger.trace(__name__, f'Stopped {__name__}.connect')
def login(self):
self._logger.trace(__name__, f'Started {__name__}.login')
try:
self._logger.debug(__name__, f'Try to login {self._mail_settings.user_name}@{self._mail_settings.host}:{self._mail_settings.port}')
self._server.login(self._mail_settings.user_name, CredentialManager.decrypt(self._mail_settings.credentials))
self._logger.info(__name__, f'Logged on as {self._mail_settings.user_name} to {self._mail_settings.host}:{self._mail_settings.port}')
except Exception as e:
self._logger.error(__name__, 'Cannot login to mail server', e)
self._logger.trace(__name__, f'Stopped {__name__}.login')
def send_mail(self, email: EMail):
self._logger.trace(__name__, f'Started {__name__}.send_mail')
try:
self.login()
email.body += f'\n\nDies ist eine automatische E-Mail.' \
f'\nGesendet von {self._environment.application_name}-{self._environment.environment_name}@{self._environment.host_name} für ' \
f'{self._environment.customer}.'
self._logger.debug(__name__, f'Try to send email to {email.receiver_list}')
self._server.sendmail(self._mail_settings.user_name, email.receiver_list, email.get_content(self._mail_settings.user_name))
self._logger.info(__name__, f'Sent email to {email.receiver_list}')
except Exception as e:
self._logger.error(__name__, f'Cannot send mail to {email.receiver_list}', e)
self._logger.trace(__name__, f'Stopped {__name__}.send_mail')

View File

@ -0,0 +1,17 @@
from abc import abstractmethod
from cpl.dependency_injection.service_abc import ServiceABC
from cpl.mailing.email import EMail
class EMailClientABC(ServiceABC):
@abstractmethod
def __init__(self):
ServiceABC.__init__(self)
@abstractmethod
def connect(self): pass
@abstractmethod
def send_mail(self, email: EMail): pass

View File

@ -0,0 +1,59 @@
import traceback
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.console.console import Console
from cpl.mailing.email_client_settings_name import EMailClientSettingsName
class EMailClientSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._host: str = ''
self._port: int = 0
self._user_name: str = ''
self._credentials: str = ''
@property
def host(self) -> str:
return self._host
@host.setter
def host(self, host: str) -> None:
self._host = host
@property
def port(self) -> int:
return self._port
@port.setter
def port(self, port: int) -> None:
self._port = port
@property
def user_name(self) -> str:
return self._user_name
@user_name.setter
def user_name(self, user_name: str) -> None:
self._user_name = user_name
@property
def credentials(self) -> str:
return self._credentials
@credentials.setter
def credentials(self, credentials: str) -> None:
self._credentials = credentials
def from_dict(self, settings: dict):
try:
self._host = settings[EMailClientSettingsName.host.value]
self._port = settings[EMailClientSettingsName.port.value]
self._user_name = settings[EMailClientSettingsName.user_name.value]
self._credentials = settings[EMailClientSettingsName.credentials.value]
except Exception as e:
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')

0
src/cpl/time/__init__.py Normal file
View File

View File

@ -0,0 +1,61 @@
import traceback
from typing import Optional
from cpl.configuration.configuration_model_abc import ConfigurationModelABC
from cpl.console.console import Console
from cpl.console.foreground_color import ForegroundColor
from cpl.time.time_format_settings_names import TimeFormatSettingsNames
class TimeFormatSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._date_format: Optional[str] = None
self._time_format: Optional[str] = None
self._date_time_format: Optional[str] = None
self._date_time_log_format: Optional[str] = None
@property
def date_format(self) -> str:
return self._date_format
@date_format.setter
def date_format(self, date_format: str) -> None:
self._date_format = date_format
@property
def time_format(self) -> str:
return self._time_format
@time_format.setter
def time_format(self, time_format: str):
self._time_format = time_format
@property
def date_time_format(self) -> str:
return self._date_time_format
@date_time_format.setter
def date_time_format(self, date_time_format: str) -> None:
self._date_time_format = date_time_format
@property
def date_time_log_format(self):
return self._date_time_log_format
@date_time_log_format.setter
def date_time_log_format(self, date_time_now_format: str) -> None:
self._date_time_log_format = date_time_now_format
def from_dict(self, settings: dict):
try:
self._date_format = settings[TimeFormatSettingsNames.date_format.value]
self._time_format = settings[TimeFormatSettingsNames.time_format.value]
self._date_time_format = settings[TimeFormatSettingsNames.date_time_format.value]
self._date_time_log_format = settings[TimeFormatSettingsNames.date_time_log_format.value]
except Exception as e:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')
Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')
Console.set_foreground_color(ForegroundColor.default)

View File

0
src/cpl_cli/__init__.py Normal file
View File

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli.command
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli.command'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli.command.base
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli.command.base'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .command_base import CommandBase
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,15 +0,0 @@
from abc import ABC, abstractmethod
class CommandBase(ABC):
@abstractmethod
def __init__(self):
self._aliases: list[str] = []
@property
def aliases(self):
return self._aliases
@abstractmethod
def run(self, args: list[str]): pass

View File

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli.cpl_cli
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli.cpl_cli'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .cli import CLI
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,42 +0,0 @@
import sys
import traceback
from sh_edraft.cli.cpl_cli.commands.build.build import Build
from sh_edraft.cli.cpl_cli.commands.help import Help
from sh_edraft.cli.cpl_cli.commands.new import New
from sh_edraft.cli.cpl_cli.commands.publish.publish import Publish
from sh_edraft.cli.cpl_cli.commands.version import Version
from sh_edraft.cli.interpreter.interpreter import Interpreter
from sh_edraft.console.console import Console
class CLI:
def __init__(self):
self._interpreter = Interpreter()
def setup(self):
self._interpreter.add_command(Build())
self._interpreter.add_command(Help())
self._interpreter.add_command(New())
self._interpreter.add_command(Publish())
self._interpreter.add_command(Version())
def main(self):
string = ' '.join(sys.argv[1:])
try:
self._interpreter.interpret(string)
except Exception as e:
tb = traceback.format_exc()
Console.error(str(e), tb)
Console.error('Run \'cpl help\'')
def main():
cli = CLI()
cli.setup()
cli.main()
if __name__ == '__main__':
main()

View File

@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli.cpl_cli.commands
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli.cpl_cli.commands'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .version import Version
from .help import Help
from .new import New
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli.cpl_cli.commands.build
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli.cpl_cli.commands.build'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .app import BuildApp
from .build import Build
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,47 +0,0 @@
from typing import Optional
from sh_edraft.configuration.base.configuration_base import ConfigurationBase
from sh_edraft.hosting.application_host import ApplicationHost
from sh_edraft.hosting.base.application_base import ApplicationBase
from sh_edraft.logging.logger import Logger
from sh_edraft.logging.base.logger_base import LoggerBase
from sh_edraft.publish.publisher import Publisher
from sh_edraft.publish.base.publisher_base import PublisherBase
from sh_edraft.service.providing.base.service_provider_base import ServiceProviderBase
class BuildApp(ApplicationBase):
def __init__(self):
ApplicationBase.__init__(self)
self._app_host: Optional[ApplicationHost] = None
self._services: Optional[ServiceProviderBase] = None
self._configuration: Optional[ConfigurationBase] = None
self._logger: Optional[LoggerBase] = None
self._publisher: Optional[PublisherBase] = None
def create_application_host(self):
self._app_host = ApplicationHost()
self._configuration = self._app_host.configuration
self._services = self._app_host.services
def create_configuration(self):
self._configuration.add_json_file(f'build.json')
def create_services(self):
# Add and create logger
self._services.add_singleton(LoggerBase, Logger)
self._logger = self._services.get_service(LoggerBase)
# Add and create publisher
self._services.add_singleton(PublisherBase, Publisher)
self._publisher: Publisher = self._services.get_service(PublisherBase)
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}')
self._publisher.create()
self._publisher.build()

View File

@ -1,23 +0,0 @@
from sh_edraft.cli.command.base.command_base import CommandBase
from sh_edraft.cli.cpl_cli.commands.build.app import BuildApp
from sh_edraft.console.console import Console
class Build(CommandBase):
def __init__(self):
CommandBase.__init__(self)
self._app = BuildApp()
self._aliases.append('-b')
self._aliases.append('-B')
def run(self, args: list[str]):
if len(args) > 0:
Console.error(f'Invalid arguments {args}')
Console.error('Run \'cpl help\'')
self._app.create_application_host()
self._app.create_configuration()
self._app.create_services()
self._app.main()

View File

@ -1,27 +0,0 @@
from sh_edraft.cli.command.base.command_base import CommandBase
from sh_edraft.console.console import Console
class Help(CommandBase):
def __init__(self):
CommandBase.__init__(self)
self._aliases.append('-h')
self._aliases.append('-H')
def run(self, args: list[str]):
Console.write_line('Available Commands:')
commands = [
['build (-b|-B)', 'Prepares files for publishing into an output directory named dist/ at the given output path. Must be executed from within a workspace directory.'],
['help (-h|-H)', 'Lists available commands and their short descriptions.'],
['new', 'Creates a new file or package.'],
['publish (-p|-P)', 'Prepares files for publishing into an output directory named dist/ at the given output path and executes setup.py. Must be executed from within a workspace directory.'],
['version (-v|-V)', 'Outputs CPL CLI version.']
]
for name, description in commands:
Console.set_foreground_color('blue')
Console.write(f'\n\t{name} ')
Console.set_foreground_color('default')
Console.write(f'{description}')
Console.write('\n')

View File

@ -1,97 +0,0 @@
import os
from sh_edraft.cli.command.base.command_base import CommandBase
from sh_edraft.console.console import Console
class New(CommandBase):
def __init__(self):
CommandBase.__init__(self)
def run(self, args: list[str]):
rel_path = f'{os.path.dirname(__file__)}/../'
if len(args) == 0:
Console.error(f'Expected arguments {args}')
Console.error('Run \'cpl help\'')
return
elif len(args) != 2:
Console.error(f'Invalid arguments {args}')
Console.error('Run \'cpl help\'')
return
if not os.path.isdir(f'{rel_path}/templates/{args[0]}'):
Console.error(f'Unexpected argument {args[0]}')
Console.error('Run \'cpl help\'')
sub_args = args[1:]
if len(sub_args) != 1:
Console.error(f'Unexpected argument {sub_args[1]}')
Console.error('Run \'cpl help\'')
if not (sub_args[0].startswith('.') or sub_args[0].startswith('/')):
full_path = f'./{sub_args[0]}'
else:
full_path = sub_args[0]
name = os.path.basename(full_path)
path = os.path.dirname(full_path)
if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']:
if not os.path.isdir(path):
os.makedirs(path)
else:
if not os.path.isdir(full_path):
os.makedirs(full_path)
for r, d, f in os.walk(f'{rel_path}/templates/{args[0]}'):
for file in f:
template_content = ''
with open(f'{r}/{file}') as template:
template_content = template.read()
template.close()
file = file.replace('txt', 'py')
if args[0] in ['base', 'class', 'configmodel', 'enum', 'service']:
suffix = None
if args[0] == 'base':
suffix = 'base'
elif args[0] == 'configmodel':
suffix = 'settings'
elif args[0] == 'service':
suffix = 'service'
if suffix is not None:
file_path = f'{path}/{name}_{suffix}.py'
else:
file_path = f'{path}/{name}.py'
else:
file_path = f'{full_path}/{file}'
with open(file_path, 'w+') as pyfile:
if name[0].islower():
name = f'{name[0].upper()}{name[1:]}'
if args[0] == 'base':
template_content = template_content.replace('$Name', f'{name}Base')
pyfile.write(template_content)
elif args[0] == 'configmodel':
template_content = template_content.replace('$Name', f'{name}Settings')
pyfile.write(template_content)
elif args[0] == 'service':
template_content = template_content.replace('$Name', f'{name}Service')
template_content = template_content.replace('$Base', f'{name}Base')
pyfile.write(template_content)
else:
template_content = template_content.replace('$Name', name)
pyfile.write(template_content)
pyfile.close()

View File

@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli.cpl_cli.commands.publish
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli.cpl_cli.commands.publish'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .app import PublishApp
from .publish import Publish
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,48 +0,0 @@
from typing import Optional
from sh_edraft.configuration.base.configuration_base import ConfigurationBase
from sh_edraft.hosting.application_host import ApplicationHost
from sh_edraft.hosting.base.application_base import ApplicationBase
from sh_edraft.logging.logger import Logger
from sh_edraft.logging.base.logger_base import LoggerBase
from sh_edraft.publish.publisher import Publisher
from sh_edraft.publish.base.publisher_base import PublisherBase
from sh_edraft.service.providing.base.service_provider_base import ServiceProviderBase
class PublishApp(ApplicationBase):
def __init__(self):
ApplicationBase.__init__(self)
self._app_host: Optional[ApplicationHost] = None
self._services: Optional[ServiceProviderBase] = None
self._configuration: Optional[ConfigurationBase] = None
self._logger: Optional[LoggerBase] = None
self._publisher: Optional[PublisherBase] = None
def create_application_host(self):
self._app_host = ApplicationHost()
self._configuration = self._app_host.configuration
self._services = self._app_host.services
def create_configuration(self):
self._configuration.add_json_file(f'build.json')
def create_services(self):
# Add and create logger
self._services.add_singleton(LoggerBase, Logger)
self._logger = self._services.get_service(LoggerBase)
# Add and create publisher
self._services.add_singleton(PublisherBase, Publisher)
self._publisher: Publisher = self._services.get_service(PublisherBase)
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}')
self._publisher.create()
self._publisher.build()
self._publisher.publish()

View File

@ -1,23 +0,0 @@
from sh_edraft.cli.command.base.command_base import CommandBase
from sh_edraft.cli.cpl_cli.commands.publish.app import PublishApp
from sh_edraft.console.console import Console
class Publish(CommandBase):
def __init__(self):
CommandBase.__init__(self)
self._app = PublishApp()
self._aliases.append('-p')
self._aliases.append('-P')
def run(self, args: list[str]):
if len(args) > 0:
Console.error(f'Invalid arguments {args}')
Console.error('Run \'cpl help\'')
self._app.create_application_host()
self._app.create_configuration()
self._app.create_services()
self._app.main()

View File

@ -1,42 +0,0 @@
import pkgutil
import sys
import platform
import pkg_resources
import sh_edraft
from sh_edraft import cli
from sh_edraft.cli.command.base.command_base import CommandBase
from sh_edraft.console.console import Console
class Version(CommandBase):
def __init__(self):
CommandBase.__init__(self)
self._aliases.append('-v')
self._aliases.append('-V')
def run(self, args: list[str]):
Console.set_foreground_color('yellow')
Console.banner('CPL CLI')
Console.set_foreground_color('default')
Console.write_line(f'Common Python Library CLI: {cli.__version__}')
Console.write_line(f'Python: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')
Console.write_line(f'OS: {platform.system()} {platform.processor()}')
Console.write_line('CPL:')
packages = []
for importer, modname, is_pkg in pkgutil.iter_modules(sh_edraft.__path__):
module = importer.find_module(modname).load_module(modname)
packages.append([f'{modname}', module.__version__])
Console.table(['Name', 'Version'], packages)
Console.write_line('\nPython Packages:')
packages = []
deps = dict(tuple(str(ws).split()) for ws in pkg_resources.working_set)
for p in deps:
packages.append([p, deps[p]])
Console.table(['Name', 'Version'], packages)

View File

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

View File

@ -1,22 +0,0 @@
{
"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": "build/logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "INFO",
"FileLogLevel": "INFO"
},
"PublishSettings": {
"SourcePath": "./",
"DistPath": "build/dist",
"Templates": [],
"IncludedFiles": [],
"ExcludedFiles": [],
"TemplateEnding": "_template.txt"
}
}

View File

@ -1,8 +0,0 @@
from program import Program
if __name__ == '__main__':
program = Program()
program.create_application_host()
program.create_configuration()
program.create_services()
program.main()

View File

@ -1,43 +0,0 @@
from typing import Optional
from sh_edraft.configuration.base import ConfigurationBase
from sh_edraft.hosting import ApplicationHost
from sh_edraft.hosting.base import ApplicationBase
from sh_edraft.logging import Logger
from sh_edraft.logging.base import LoggerBase
from sh_edraft.service.providing.base import ServiceProviderBase
class Program(ApplicationBase):
def __init__(self):
ApplicationBase.__init__(self)
self._app_host: Optional[ApplicationHost] = None
self._services: Optional[ServiceProviderBase] = None
self._configuration: Optional[ConfigurationBase] = None
self._logger: Optional[LoggerBase] = None
def create_application_host(self):
self._app_host = ApplicationHost()
self._configuration = self._app_host.configuration
self._services = self._app_host.services
def create_configuration(self):
self._configuration.add_environment_variables('PYTHON_')
self._configuration.add_environment_variables('CPL_')
self._configuration.add_argument_variables()
self._configuration.add_json_file(f'appsettings.json')
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.environment_name}.json', optional=True)
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True)
def create_services(self):
# Add and create logger
self._services.add_singleton(LoggerBase, Logger)
self._logger = self._services.get_service(LoggerBase)
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}')

View File

@ -1,4 +0,0 @@
class $Name:
def __init__(self):
pass

View File

@ -1,20 +0,0 @@
import traceback
from sh_edraft.configuration.base import ConfigurationModelBase
from sh_edraft.console import Console
from sh_edraft.console.model import ForegroundColor
class $Name(ConfigurationModelBase):
def __init__(self):
ConfigurationModelBase.__init__(self)
def from_dict(self, settings: dict):
try:
pass
except Exception as e:
Console.set_foreground_color(ForegroundColor.red)
Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')
Console.write_line(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')
Console.set_foreground_color(ForegroundColor.default)

View File

@ -1,6 +0,0 @@
from enum import Enum
class $Name(Enum):
pass

View File

@ -1,6 +0,0 @@
class $Name($Base):
def __init__(self):
TestBase.__init__(self)
self.create()

View File

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.cli.interpreter
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.cli.interpreter'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .interpreter import Interpreter
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,33 +0,0 @@
from sh_edraft.cli.command.base.command_base import CommandBase
from sh_edraft.console.console import Console
class Interpreter:
def __init__(self):
self._commands: list[CommandBase] = []
def add_command(self, command: CommandBase):
self._commands.append(command)
def remove_command(self, command: CommandBase):
self._commands.remove(command)
def interpret(self, input_string: str):
input_list = input_string.split(' ')
command = input_list[0]
if command is None or command == '':
Console.error(f'Expected command')
Console.error('Run \'cpl help\'')
return
args = input_list[1:] if len(input_list) > 1 else []
cmd = next(
(cmd for cmd in self._commands if type(cmd).__name__.lower() == command or command in cmd.aliases),
None)
if cmd is not None:
cmd.run(args)
else:
Console.error(f'Unexpected command {command}')
Console.error('Run \'cpl help\'')

View File

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.publishing
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.publishing'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .publisher import Publisher
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.publishing.base
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.publishing.base'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .publisher_base import PublisherBase
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

View File

@ -1,29 +0,0 @@
# -*- coding: utf-8 -*-
"""
sh_edraft.publishing.model
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'sh_edraft.publishing.model'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.10'
from collections import namedtuple
# imports:
from .template import Template
from .template_enum import TemplateEnum
from .publish_settings_model import PublishSettings
from .publish_settings_name import PublishSettingsName
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=10)

45
src/tests/Application.py Normal file
View File

@ -0,0 +1,45 @@
from typing import Optional
from cpl.application.application_abc import ApplicationABC
from cpl.console.console import Console
from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email import EMail
from cpl.mailing.email_client_abc import EMailClientABC
class Application(ApplicationABC):
def __init__(self):
ApplicationABC.__init__(self)
self._logger: Optional[LoggerABC] = None
self._mailer: Optional[EMailClientABC] = None
def test_send_mail(self):
mail = EMail()
mail.add_header('Mime-Version: 1.0')
mail.add_header('Content-Type: text/plain; charset=utf-8')
mail.add_header('Content-Transfer-Encoding: quoted-printable')
mail.add_receiver('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 test')
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')
def run(self):
self._logger = self._services.get_service(LoggerABC)
self._mailer = self._services.get_service(EMailClientABC)
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}')
self.test_send_mail()
# self.test_console()

52
src/tests/Startup.py Normal file
View File

@ -0,0 +1,52 @@
from typing import Optional
from cpl.application.application_host import ApplicationHost
from cpl.application.application_host_abc import ApplicationHostABC
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_provider_base import ServiceProviderABC
from cpl.logging.logger import Logger
from cpl.logging.logger_abc import LoggerABC
from cpl.mailing.email_client import EMailClient
from cpl.mailing.email_client_abc import EMailClientABC
from cpl.utils.credential_manager import CredentialManager
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
self._app_host: Optional[ApplicationHostABC] = None
self._configuration: Optional[ConfigurationABC] = None
self._services: Optional[ServiceProviderABC] = None
def create_application_host(self) -> ApplicationHostABC:
self._app_host = ApplicationHost()
self._configuration = self._app_host.configuration
self._services = self._app_host.services
return self._app_host
def create_configuration(self) -> ConfigurationABC:
self._configuration.add_environment_variables('PYTHON_')
self._configuration.add_environment_variables('CPL_')
self._configuration.add_argument_variables()
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 create_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)
return self._services

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
"""
tests
~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2020 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'tests'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 sh-edraft.de'
__version__ = '2020.12.9'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major=2020, minor=12, micro=9)

View File

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

View File

@ -16,5 +16,48 @@
"Port": "587", "Port": "587",
"UserName": "dev-srv@sh-edraft.de", "UserName": "dev-srv@sh-edraft.de",
"Credentials": "RmBOQX1eNFYiYjgsSid3fV1nelc2WA==" "Credentials": "RmBOQX1eNFYiYjgsSid3fV1nelc2WA=="
},
"PublishSettings": {
"SourcePath": "../",
"DistPath": "../../dist",
"Templates": [
{
"TemplatePath": "../../publish_templates/all_template.txt",
"Name": "all",
"Description": "",
"LongDescription": "",
"CopyrightDate": "2020",
"CopyrightName": "sh-edraft.de",
"LicenseName": "MIT",
"LicenseDescription": ", see LICENSE for more details.",
"Title": "",
"Author": "Sven Heidemann",
"Version": {
"Major": 2020,
"Minor": 12,
"Micro": 9
}
},
{
"TemplatePath": "../../publish_templates/all_template.txt",
"Name": "sh_edraft",
"Description": "common python library",
"LongDescription": "Library to share common classes and models used at sh-edraft.de",
"CopyrightDate": "2020",
"CopyrightName": "sh-edraft.de",
"LicenseName": "MIT",
"LicenseDescription": ", see LICENSE for more details.",
"Title": "",
"Author": "Sven Heidemann",
"Version": {
"Major": 2020,
"Minor": 12,
"Micro": 9
}
}
],
"IncludedFiles": [],
"ExcludedFiles": [],
"TemplateEnding": "_template.txt"
} }
} }

View File

@ -5,16 +5,25 @@
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
}, },
"LoggingSettings": { "LoggingSettings": {
"Path": "logs/", "Path": "logs/",
"Filename": "log_$start_time.log", "Filename": "log_$start_time.log",
"ConsoleLogLevel": "TRACE", "ConsoleLogLevel": "TRACE",
"FileLogLevel": "TRACE" "FileLogLevel": "TRACE"
}, },
"EMailClientSettings": { "EMailClientSettings": {
"Host": "mail.sh-edraft.de", "Host": "mail.sh-edraft.de",
"Port": "587", "Port": "587",
"UserName": "dev-srv@sh-edraft.de", "UserName": "dev-srv@sh-edraft.de",
"Credentials": "RmBOQX1eNFYiYjgsSid3fV1nelc2WA==" "Credentials": "RmBOQX1eNFYiYjgsSid3fV1nelc2WA=="
},
"DatabaseSettings": {
"AuthPlugin": "mysql_native_password",
"ConnectionString": "mysql+mysqlconnector://sh_cpl:$credentials@localhost/sh_cpl",
"Credentials": "MHZhc0Y2bjhKc1VUMWV0Qw==",
"Encoding": "utf8mb4"
} }
} }

0
src/tests/cpl.json Normal file
View File

8
src/tests/main.py Normal file
View File

@ -0,0 +1,8 @@
from tests.Application import Application
from tests.Startup import Startup
if __name__ == '__main__':
app = Application()
app.use_startup(Startup)
app.build()
app.run()

View File

@ -1,14 +0,0 @@
from sqlalchemy import Column, Integer, String
from sh_edraft.database.model import DBModel
class City(DBModel):
__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

@ -1,18 +0,0 @@
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sh_edraft.database.model import DBModel
from tests_dev.db.city import City as CityModel
class User(DBModel):
__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("City")
def __init__(self, name: str, city: CityModel):
self.Name = name
self.City_Id = city.Id
self.City = city

View File

@ -1,23 +0,0 @@
from sh_edraft.database.context.base import DatabaseContextBase
from tests_dev.db.city import City
from tests_dev.db.user import User
from tests_dev.db.user_repo_base import UserRepoBase
class UserRepo(UserRepoBase):
def __init__(self, db_context: DatabaseContextBase):
UserRepoBase.__init__(self)
self._session = db_context.session
self._user_query = db_context.session.query(User)
def create(self): pass
def add_test_user(self):
city = City('Haren', '49733')
city2 = City('Meppen', '49716')
self._session.add(city2)
user = User('TestUser', city)
self._session.add(user)
self._session.commit()

View File

@ -1,10 +0,0 @@
from abc import abstractmethod
from sh_edraft.service.base import ServiceBase
class UserRepoBase(ServiceBase):
@abstractmethod
def __init__(self):
ServiceBase.__init__(self)

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