django-cfg 1.3.13__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/accounts/admin/user_admin.py +39 -16
- django_cfg/apps/accounts/serializers/profile.py +1 -1
- django_cfg/apps/accounts/services/otp_service.py +18 -11
- django_cfg/apps/accounts/signals.py +15 -24
- django_cfg/apps/accounts/utils/notifications.py +217 -358
- django_cfg/apps/accounts/views/otp.py +2 -2
- django_cfg/apps/accounts/views/webhook.py +1 -1
- django_cfg/apps/agents/core/django_agent.py +1 -1
- django_cfg/apps/api/commands/views.py +66 -83
- django_cfg/apps/api/health/drf_views.py +269 -0
- django_cfg/apps/api/health/serializers.py +45 -0
- django_cfg/apps/api/health/urls.py +6 -1
- django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
- django_cfg/apps/knowbase/admin/document_admin.py +136 -270
- django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
- django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
- django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
- django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
- django_cfg/apps/knowbase/config/constance_fields.py +1 -1
- django_cfg/apps/knowbase/config/settings.py +2 -2
- django_cfg/apps/knowbase/mixins/__init__.py +19 -2
- django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
- django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
- django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
- django_cfg/apps/knowbase/mixins/creator.py +10 -10
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
- django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
- django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
- django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
- django_cfg/apps/knowbase/mixins/service.py +2 -2
- django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
- django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
- django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
- django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
- django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
- django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
- django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
- django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
- django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
- django_cfg/apps/knowbase/services/embedding/models.py +18 -14
- django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
- django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
- django_cfg/apps/leads/tests.py +1 -1
- django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
- django_cfg/apps/payments/admin/balance_admin.py +1 -1
- django_cfg/apps/payments/admin/currencies_admin.py +1 -1
- django_cfg/apps/payments/admin/payments_admin.py +1 -1
- django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
- django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
- django_cfg/apps/payments/admin_interface/views/base.py +29 -2
- django_cfg/apps/payments/apps.py +1 -1
- django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
- django_cfg/apps/payments/config/helpers.py +3 -2
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
- django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
- django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
- django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
- django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
- django_cfg/apps/payments/management/commands/test_providers.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +1 -1
- django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
- django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
- django_cfg/apps/payments/models/balance.py +2 -2
- django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
- django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
- django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
- django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
- django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
- django_cfg/apps/payments/models/payments.py +2 -2
- django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
- django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
- django_cfg/apps/payments/services/core/base.py +1 -1
- django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
- django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
- django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
- django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
- django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
- django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
- django_cfg/apps/payments/services/core/payment_service.py +124 -612
- django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
- django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
- django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
- django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
- django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
- django_cfg/apps/payments/services/providers/base.py +1 -1
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
- django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
- django_cfg/apps/payments/services/providers/registry.py +1 -1
- django_cfg/apps/payments/services/providers/sync_service.py +1 -1
- django_cfg/apps/payments/signals/__init__.py +1 -1
- django_cfg/apps/payments/signals/api_key_signals.py +1 -1
- django_cfg/apps/payments/signals/balance_signals.py +1 -1
- django_cfg/apps/payments/signals/payment_signals.py +1 -1
- django_cfg/apps/payments/signals/subscription_signals.py +1 -1
- django_cfg/apps/payments/views/api/api_keys.py +1 -1
- django_cfg/apps/payments/views/api/balances.py +1 -1
- django_cfg/apps/payments/views/api/base.py +1 -1
- django_cfg/apps/payments/views/api/currencies.py +1 -1
- django_cfg/apps/payments/views/api/payments.py +1 -1
- django_cfg/apps/payments/views/api/subscriptions.py +1 -1
- django_cfg/apps/payments/views/api/webhooks.py +1 -1
- django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
- django_cfg/apps/payments/views/serializers/balances.py +1 -1
- django_cfg/apps/payments/views/serializers/currencies.py +1 -1
- django_cfg/apps/payments/views/serializers/payments.py +1 -1
- django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
- django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
- django_cfg/apps/support/admin/support_admin.py +21 -13
- django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
- django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
- django_cfg/apps/support/utils/support_email_service.py +1 -1
- django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
- django_cfg/apps/tasks/utils/simulator.py +1 -1
- django_cfg/apps/tasks/views/dashboard.py +33 -3
- django_cfg/apps/urls.py +5 -1
- django_cfg/cli/README.md +57 -471
- django_cfg/cli/commands/create_project.py +140 -529
- django_cfg/cli/main.py +13 -10
- django_cfg/core/__init__.py +63 -6
- django_cfg/core/base/__init__.py +5 -0
- django_cfg/core/base/config_model.py +652 -0
- django_cfg/core/builders/__init__.py +11 -0
- django_cfg/core/builders/apps_builder.py +258 -0
- django_cfg/core/builders/middleware_builder.py +115 -0
- django_cfg/core/builders/security_builder.py +96 -0
- django_cfg/core/config.py +20 -892
- django_cfg/core/constants.py +69 -0
- django_cfg/core/environment/__init__.py +9 -0
- django_cfg/core/exceptions.py +45 -298
- django_cfg/core/generation/__init__.py +51 -0
- django_cfg/core/generation/core_generators/__init__.py +0 -0
- django_cfg/core/generation/core_generators/settings.py +90 -0
- django_cfg/core/generation/core_generators/static.py +82 -0
- django_cfg/core/generation/core_generators/templates.py +141 -0
- django_cfg/core/generation/data_generators/__init__.py +15 -0
- django_cfg/core/generation/data_generators/cache.py +132 -0
- django_cfg/core/generation/data_generators/database.py +117 -0
- django_cfg/core/generation/generation.py +92 -0
- django_cfg/core/generation/integration_generators/__init__.py +21 -0
- django_cfg/core/generation/integration_generators/api.py +237 -0
- django_cfg/core/generation/integration_generators/sessions.py +65 -0
- django_cfg/core/generation/integration_generators/tailwind.py +54 -0
- django_cfg/core/generation/integration_generators/tasks.py +92 -0
- django_cfg/core/generation/integration_generators/third_party.py +144 -0
- django_cfg/core/generation/orchestrator.py +285 -0
- django_cfg/core/generation/protocols.py +30 -0
- django_cfg/core/generation/security_generators/__init__.py +0 -0
- django_cfg/core/generation/utility_generators/__init__.py +24 -0
- django_cfg/core/generation/utility_generators/email.py +58 -0
- django_cfg/core/generation/utility_generators/i18n.py +66 -0
- django_cfg/core/generation/utility_generators/limits.py +58 -0
- django_cfg/core/generation/utility_generators/logging.py +66 -0
- django_cfg/core/generation/utility_generators/security.py +101 -0
- django_cfg/core/generation/utils/__init__.py +0 -0
- django_cfg/core/generation/utils/helpers.py +32 -0
- django_cfg/core/integration/__init__.py +18 -25
- django_cfg/core/integration/display/startup.py +146 -133
- django_cfg/core/integration/url_integration.py +13 -2
- django_cfg/core/services/__init__.py +5 -0
- django_cfg/core/services/config_service.py +121 -0
- django_cfg/core/state/__init__.py +9 -0
- django_cfg/core/state/registry.py +84 -0
- django_cfg/core/types/__init__.py +15 -0
- django_cfg/core/types/aliases.py +15 -0
- django_cfg/core/types/enums.py +49 -0
- django_cfg/dashboard/DEBUG_README.md +105 -0
- django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
- django_cfg/dashboard/__init__.py +24 -0
- django_cfg/dashboard/components.py +308 -0
- django_cfg/dashboard/debug.py +176 -0
- django_cfg/dashboard/management/__init__.py +0 -0
- django_cfg/dashboard/management/commands/__init__.py +0 -0
- django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
- django_cfg/dashboard/sections/__init__.py +1 -0
- django_cfg/dashboard/sections/base.py +128 -0
- django_cfg/dashboard/sections/commands.py +32 -0
- django_cfg/dashboard/sections/overview.py +394 -0
- django_cfg/dashboard/sections/stats.py +48 -0
- django_cfg/dashboard/sections/system.py +73 -0
- django_cfg/management/commands/check_settings.py +6 -2
- django_cfg/management/commands/clear_constance.py +6 -1
- django_cfg/management/commands/create_token.py +5 -4
- django_cfg/management/commands/generate.py +5 -0
- django_cfg/management/commands/list_urls.py +7 -2
- django_cfg/management/commands/migrate_all.py +6 -2
- django_cfg/management/commands/migrator.py +6 -1
- django_cfg/management/commands/rundramatiq.py +6 -1
- django_cfg/management/commands/rundramatiq_simulator.py +11 -4
- django_cfg/management/commands/runserver_ngrok.py +9 -7
- django_cfg/management/commands/script.py +25 -21
- django_cfg/management/commands/show_config.py +6 -1
- django_cfg/management/commands/show_urls.py +8 -3
- django_cfg/management/commands/superuser.py +5 -4
- django_cfg/management/commands/task_clear.py +8 -3
- django_cfg/management/commands/task_status.py +8 -3
- django_cfg/management/commands/test_email.py +6 -1
- django_cfg/management/commands/test_telegram.py +6 -1
- django_cfg/management/commands/test_twilio.py +6 -1
- django_cfg/management/commands/tree.py +7 -4
- django_cfg/models/__init__.py +88 -3
- django_cfg/models/api/__init__.py +27 -0
- django_cfg/models/{api.py → api/config.py} +1 -1
- django_cfg/models/api/drf/__init__.py +21 -0
- django_cfg/models/api/drf/config.py +101 -0
- django_cfg/models/api/drf/redoc.py +31 -0
- django_cfg/models/api/drf/spectacular.py +129 -0
- django_cfg/models/api/drf/swagger.py +59 -0
- django_cfg/models/{api_keys.py → api/keys.py} +16 -6
- django_cfg/models/{limits.py → api/limits.py} +0 -1
- django_cfg/models/base/__init__.py +14 -0
- django_cfg/models/django/__init__.py +16 -0
- django_cfg/models/{constance.py → django/constance.py} +1 -1
- django_cfg/models/{environment.py → django/environment.py} +1 -1
- django_cfg/models/infrastructure/__init__.py +17 -0
- django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
- django_cfg/models/infrastructure/database/__init__.py +22 -0
- django_cfg/models/infrastructure/database/config.py +265 -0
- django_cfg/models/infrastructure/database/converters.py +91 -0
- django_cfg/models/infrastructure/database/parsers.py +96 -0
- django_cfg/models/infrastructure/database/routing.py +85 -0
- django_cfg/models/infrastructure/database/validators.py +170 -0
- django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
- django_cfg/models/{security.py → infrastructure/security.py} +2 -2
- django_cfg/models/ngrok/__init__.py +11 -0
- django_cfg/models/ngrok/auth.py +37 -0
- django_cfg/models/ngrok/config.py +77 -0
- django_cfg/models/ngrok/tunnel.py +35 -0
- django_cfg/models/payments/__init__.py +20 -0
- django_cfg/models/payments/api_keys.py +57 -0
- django_cfg/models/{payments.py → payments/config.py} +56 -154
- django_cfg/models/payments/providers/__init__.py +15 -0
- django_cfg/models/payments/providers/base.py +25 -0
- django_cfg/models/payments/providers/nowpayments.py +48 -0
- django_cfg/models/services/__init__.py +18 -0
- django_cfg/models/services/base.py +65 -0
- django_cfg/models/{email.py → services/email.py} +1 -1
- django_cfg/models/services/telegram.py +172 -0
- django_cfg/models/tasks/__init__.py +51 -0
- django_cfg/models/tasks/backends.py +250 -0
- django_cfg/models/tasks/config.py +314 -0
- django_cfg/models/tasks/utils.py +174 -0
- django_cfg/modules/base.py +18 -3
- django_cfg/modules/django_admin/decorators/actions.py +1 -1
- django_cfg/modules/django_admin/decorators/display.py +1 -1
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
- django_cfg/modules/django_cfg_rpc_client/README.md +346 -0
- django_cfg/modules/django_cfg_rpc_client/__init__.py +51 -0
- django_cfg/modules/django_cfg_rpc_client/client.py +540 -0
- django_cfg/modules/django_cfg_rpc_client/config.py +207 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/README.md +517 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/__init__.py +11 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/apps.py +22 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/monitor.py +435 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js +373 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html +76 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html +200 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/urls.py +22 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/urls_admin.py +9 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/views.py +251 -0
- django_cfg/modules/django_cfg_rpc_client/exceptions.py +201 -0
- django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
- django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
- django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
- django_cfg/modules/django_drf_theme/README.md +207 -0
- django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
- django_cfg/modules/django_drf_theme/__init__.py +23 -0
- django_cfg/modules/django_drf_theme/apps.py +15 -0
- django_cfg/modules/django_drf_theme/renderers.py +58 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
- django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
- django_cfg/modules/django_email/__init__.py +14 -0
- django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
- django_cfg/modules/django_email/utils.py +40 -0
- django_cfg/modules/django_health/__init__.py +9 -0
- django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
- django_cfg/modules/django_llm/llm/client.py +155 -550
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
- django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
- django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
- django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
- django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
- django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
- django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
- django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
- django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
- django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
- django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
- django_cfg/modules/django_llm/translator/translator.py +150 -603
- django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
- django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
- django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
- django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
- django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
- django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
- django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
- django_cfg/modules/django_logging/__init__.py +14 -0
- django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
- django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
- django_cfg/modules/django_ngrok/__init__.py +39 -0
- django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
- django_cfg/modules/django_rpc_old/POETRY.md +344 -0
- django_cfg/modules/django_rpc_old/README.md +397 -0
- django_cfg/modules/django_rpc_old/TESTING.md +358 -0
- django_cfg/modules/django_rpc_old/__init__.py +39 -0
- django_cfg/modules/django_rpc_old/client.py +531 -0
- django_cfg/modules/django_rpc_old/config.py +279 -0
- django_cfg/modules/django_rpc_old/exceptions.py +172 -0
- django_cfg/modules/django_tailwind/README.md +478 -0
- django_cfg/modules/django_tailwind/__init__.py +7 -0
- django_cfg/modules/django_tailwind/apps.py +10 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
- django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
- django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
- django_cfg/modules/django_tasks/__init__.py +29 -0
- django_cfg/modules/django_tasks/factory.py +127 -0
- django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
- django_cfg/modules/django_tasks/settings.py +107 -0
- django_cfg/modules/django_telegram/__init__.py +29 -0
- django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
- django_cfg/modules/django_telegram/utils.py +62 -0
- django_cfg/modules/django_twilio/__init__.py +54 -107
- django_cfg/modules/django_twilio/_imports.py +30 -0
- django_cfg/modules/django_twilio/base.py +192 -0
- django_cfg/modules/django_twilio/email_otp.py +227 -0
- django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
- django_cfg/modules/django_twilio/simple_service.py +1 -2
- django_cfg/modules/django_twilio/sms.py +94 -0
- django_cfg/modules/django_twilio/twilio_service.py +2 -3
- django_cfg/modules/django_twilio/unified.py +310 -0
- django_cfg/modules/django_twilio/utils.py +190 -0
- django_cfg/modules/django_twilio/whatsapp.py +137 -0
- django_cfg/modules/django_unfold/callbacks/base.py +198 -7
- django_cfg/modules/django_unfold/callbacks/main.py +102 -10
- django_cfg/modules/django_unfold/dashboard.py +65 -43
- django_cfg/modules/django_unfold/models/config.py +13 -12
- django_cfg/modules/django_unfold/models/navigation.py +8 -3
- django_cfg/modules/django_unfold/models/tabs.py +2 -2
- django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
- django_cfg/registry/core.py +24 -26
- django_cfg/registry/modules.py +5 -2
- django_cfg/registry/services.py +20 -3
- django_cfg/registry/third_party.py +8 -8
- django_cfg/static/admin/css/dashboard.css +260 -0
- django_cfg/static/admin/js/commands.js +171 -0
- django_cfg/static/admin/js/dashboard.js +126 -0
- django_cfg/templates/admin/components/management_commands.js +375 -0
- django_cfg/templates/admin/components/progress_bar.html +18 -23
- django_cfg/templates/admin/index.html +48 -20
- django_cfg/templates/admin/index_new.html +106 -0
- django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
- django_cfg/templates/admin/sections/commands_section.html +626 -0
- django_cfg/templates/admin/sections/overview_section.html +112 -0
- django_cfg/templates/admin/sections/stats_section.html +35 -0
- django_cfg/templates/admin/sections/system_section.html +99 -0
- django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
- django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
- django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
- django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
- django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
- django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
- django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
- django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
- django_cfg/templatetags/django_cfg.py +7 -1
- django_cfg/utils/smart_defaults.py +4 -4
- django_cfg-1.4.0.dist-info/METADATA +920 -0
- {django_cfg-1.3.13.dist-info → django_cfg-1.4.0.dist-info}/RECORD +424 -195
- django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
- django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
- django_cfg/core/generation.py +0 -621
- django_cfg/management/commands/validate_config.py +0 -189
- django_cfg/models/database.py +0 -480
- django_cfg/models/drf.py +0 -272
- django_cfg/models/ngrok.py +0 -122
- django_cfg/models/services.py +0 -440
- django_cfg/models/tasks.py +0 -550
- django_cfg/modules/django_twilio/service.py +0 -942
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/rest_framework/api.html +0 -12
- django_cfg/utils/toolkit.py +0 -703
- django_cfg-1.3.13.dist-info/METADATA +0 -1029
- /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
- /django_cfg/core/{environment.py → environment/detector.py} +0 -0
- /django_cfg/models/{cors.py → api/cors.py} +0 -0
- /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
- /django_cfg/models/{base.py → base/config.py} +0 -0
- /django_cfg/models/{cfg.py → base/module.py} +0 -0
- /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
- /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
- {django_cfg-1.3.13.dist-info → django_cfg-1.4.0.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.13.dist-info → django_cfg-1.4.0.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.13.dist-info → django_cfg-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -5,7 +5,7 @@ This email service automatically configures itself based on the DjangoConfig ins
|
|
5
5
|
without requiring manual parameter passing.
|
6
6
|
"""
|
7
7
|
|
8
|
-
from typing import List, Optional, Dict, Any
|
8
|
+
from typing import List, Optional, Dict, Any
|
9
9
|
import socket
|
10
10
|
from smtplib import SMTPException
|
11
11
|
import logging
|
@@ -14,7 +14,7 @@ from django.template.loader import render_to_string
|
|
14
14
|
from django.utils.html import strip_tags
|
15
15
|
from django.conf import settings
|
16
16
|
|
17
|
-
from
|
17
|
+
from ..base import BaseCfgModule
|
18
18
|
|
19
19
|
logger = logging.getLogger(__name__)
|
20
20
|
|
@@ -22,27 +22,27 @@ logger = logging.getLogger(__name__)
|
|
22
22
|
class DjangoEmailService(BaseCfgModule):
|
23
23
|
"""
|
24
24
|
Auto-configuring email service that gets settings from DjangoConfig.
|
25
|
-
|
25
|
+
|
26
26
|
Usage:
|
27
27
|
from django_cfg.modules import DjangoEmailService
|
28
|
-
|
28
|
+
|
29
29
|
email = DjangoEmailService()
|
30
30
|
email.send_simple("Test", "Hello World!", ["user@example.com"])
|
31
31
|
"""
|
32
|
-
|
32
|
+
|
33
33
|
def __init__(self):
|
34
34
|
"""Initialize email service with auto-discovered config."""
|
35
35
|
self.config = self.get_config()
|
36
36
|
self.email_config = getattr(self.config, 'email', None)
|
37
|
-
|
37
|
+
|
38
38
|
def _handle_email_sending(self, email_func, *args, **kwargs):
|
39
39
|
"""
|
40
40
|
Wrapper for email sending with proper timeout/exception handling.
|
41
|
-
|
41
|
+
|
42
42
|
Args:
|
43
43
|
email_func: Email sending function to call
|
44
44
|
*args, **kwargs: Arguments to pass to the function
|
45
|
-
|
45
|
+
|
46
46
|
Returns:
|
47
47
|
Result of email_func or 0 on timeout/error
|
48
48
|
"""
|
@@ -63,7 +63,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
63
63
|
if not kwargs.get('fail_silently', False):
|
64
64
|
raise
|
65
65
|
return 0
|
66
|
-
|
66
|
+
|
67
67
|
def send_simple(
|
68
68
|
self,
|
69
69
|
subject: str,
|
@@ -74,19 +74,19 @@ class DjangoEmailService(BaseCfgModule):
|
|
74
74
|
) -> int:
|
75
75
|
"""
|
76
76
|
Send a simple text email.
|
77
|
-
|
77
|
+
|
78
78
|
Args:
|
79
79
|
subject: Email subject
|
80
80
|
message: Email message (plain text)
|
81
81
|
recipient_list: List of recipient email addresses
|
82
82
|
from_email: Sender email (auto-detected if not provided)
|
83
83
|
fail_silently: Whether to fail silently on errors
|
84
|
-
|
84
|
+
|
85
85
|
Returns:
|
86
86
|
Number of emails sent successfully
|
87
87
|
"""
|
88
88
|
from_email = self._get_formatted_from_email(from_email)
|
89
|
-
|
89
|
+
|
90
90
|
return self._handle_email_sending(
|
91
91
|
send_mail,
|
92
92
|
subject=subject,
|
@@ -95,7 +95,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
95
95
|
recipient_list=recipient_list,
|
96
96
|
fail_silently=fail_silently,
|
97
97
|
)
|
98
|
-
|
98
|
+
|
99
99
|
def send_html(
|
100
100
|
self,
|
101
101
|
subject: str,
|
@@ -107,7 +107,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
107
107
|
) -> int:
|
108
108
|
"""
|
109
109
|
Send an HTML email with optional plain text alternative.
|
110
|
-
|
110
|
+
|
111
111
|
Args:
|
112
112
|
subject: Email subject
|
113
113
|
html_message: HTML email content
|
@@ -115,15 +115,15 @@ class DjangoEmailService(BaseCfgModule):
|
|
115
115
|
text_message: Plain text alternative (auto-generated if not provided)
|
116
116
|
from_email: Sender email (auto-detected if not provided)
|
117
117
|
fail_silently: Whether to fail silently on errors
|
118
|
-
|
118
|
+
|
119
119
|
Returns:
|
120
120
|
Number of emails sent successfully
|
121
121
|
"""
|
122
122
|
from_email = self._get_formatted_from_email(from_email)
|
123
|
-
|
123
|
+
|
124
124
|
if text_message is None:
|
125
125
|
text_message = strip_tags(html_message)
|
126
|
-
|
126
|
+
|
127
127
|
return self._handle_email_sending(
|
128
128
|
send_mail,
|
129
129
|
subject=subject,
|
@@ -133,7 +133,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
133
133
|
html_message=html_message,
|
134
134
|
fail_silently=fail_silently,
|
135
135
|
)
|
136
|
-
|
136
|
+
|
137
137
|
def send_template(
|
138
138
|
self,
|
139
139
|
subject: str,
|
@@ -145,7 +145,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
145
145
|
) -> int:
|
146
146
|
"""
|
147
147
|
Send an email using a Django template.
|
148
|
-
|
148
|
+
|
149
149
|
Args:
|
150
150
|
subject: Email subject
|
151
151
|
template_name: Template name (without .html extension)
|
@@ -153,24 +153,24 @@ class DjangoEmailService(BaseCfgModule):
|
|
153
153
|
recipient_list: List of recipient email addresses
|
154
154
|
from_email: Sender email (auto-detected if not provided)
|
155
155
|
fail_silently: Whether to fail silently on errors
|
156
|
-
|
156
|
+
|
157
157
|
Returns:
|
158
158
|
Number of emails sent successfully
|
159
159
|
"""
|
160
160
|
from_email = self._get_formatted_from_email(from_email)
|
161
|
-
|
161
|
+
|
162
162
|
# Prepare context with auto-added values
|
163
163
|
context = self._prepare_template_context(context)
|
164
|
-
|
164
|
+
|
165
165
|
# Render HTML template
|
166
166
|
html_message = render_to_string(f"{template_name}.html", context)
|
167
|
-
|
167
|
+
|
168
168
|
# Try to render plain text template
|
169
169
|
try:
|
170
170
|
text_message = render_to_string(f"{template_name}.txt", context)
|
171
171
|
except:
|
172
172
|
text_message = strip_tags(html_message)
|
173
|
-
|
173
|
+
|
174
174
|
return self.send_html(
|
175
175
|
subject=subject,
|
176
176
|
html_message=html_message,
|
@@ -179,7 +179,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
179
179
|
from_email=from_email,
|
180
180
|
fail_silently=fail_silently,
|
181
181
|
)
|
182
|
-
|
182
|
+
|
183
183
|
def send_multipart(
|
184
184
|
self,
|
185
185
|
subject: str,
|
@@ -192,7 +192,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
192
192
|
) -> bool:
|
193
193
|
"""
|
194
194
|
Send a multipart email with attachments.
|
195
|
-
|
195
|
+
|
196
196
|
Args:
|
197
197
|
subject: Email subject
|
198
198
|
recipient_list: List of recipient email addresses
|
@@ -201,15 +201,15 @@ class DjangoEmailService(BaseCfgModule):
|
|
201
201
|
from_email: Sender email (auto-detected if not provided)
|
202
202
|
attachments: List of (filename, content, mimetype) tuples
|
203
203
|
fail_silently: Whether to fail silently on errors
|
204
|
-
|
204
|
+
|
205
205
|
Returns:
|
206
206
|
True if email was sent successfully, False otherwise
|
207
207
|
"""
|
208
208
|
from_email = self._get_formatted_from_email(from_email)
|
209
|
-
|
209
|
+
|
210
210
|
if not html_content and not text_content:
|
211
211
|
raise ValueError("Either html_content or text_content must be provided")
|
212
|
-
|
212
|
+
|
213
213
|
def _send_multipart_email():
|
214
214
|
email = EmailMultiAlternatives(
|
215
215
|
subject=subject,
|
@@ -217,24 +217,24 @@ class DjangoEmailService(BaseCfgModule):
|
|
217
217
|
from_email=from_email,
|
218
218
|
to=recipient_list,
|
219
219
|
)
|
220
|
-
|
220
|
+
|
221
221
|
if html_content:
|
222
222
|
email.attach_alternative(html_content, "text/html")
|
223
|
-
|
223
|
+
|
224
224
|
if attachments:
|
225
225
|
for filename, content, mimetype in attachments:
|
226
226
|
email.attach(filename, content, mimetype)
|
227
|
-
|
227
|
+
|
228
228
|
email.send(fail_silently=fail_silently)
|
229
229
|
return True
|
230
|
-
|
230
|
+
|
231
231
|
try:
|
232
232
|
return self._handle_email_sending(_send_multipart_email) or False
|
233
233
|
except Exception as e:
|
234
234
|
if not fail_silently:
|
235
235
|
raise e
|
236
236
|
return False
|
237
|
-
|
237
|
+
|
238
238
|
def send_with_attachments(
|
239
239
|
self,
|
240
240
|
subject: str,
|
@@ -249,7 +249,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
249
249
|
) -> bool:
|
250
250
|
"""
|
251
251
|
Universal method to send emails with attachments.
|
252
|
-
|
252
|
+
|
253
253
|
Args:
|
254
254
|
subject: Email subject
|
255
255
|
recipient_list: List of recipient email addresses
|
@@ -260,40 +260,40 @@ class DjangoEmailService(BaseCfgModule):
|
|
260
260
|
context: Template context variables (required if template_name provided)
|
261
261
|
from_email: Sender email (auto-detected if not provided)
|
262
262
|
fail_silently: Whether to fail silently on errors
|
263
|
-
|
263
|
+
|
264
264
|
Returns:
|
265
265
|
True if email was sent successfully, False otherwise
|
266
266
|
"""
|
267
267
|
html_content = None
|
268
268
|
text_content = None
|
269
|
-
|
269
|
+
|
270
270
|
if template_name:
|
271
271
|
# Template-based email
|
272
272
|
if not context:
|
273
273
|
context = {}
|
274
|
-
|
274
|
+
|
275
275
|
# Prepare context with auto-added values
|
276
276
|
context = self._prepare_template_context(context)
|
277
|
-
|
277
|
+
|
278
278
|
# Render templates
|
279
279
|
html_content = render_to_string(f"{template_name}.html", context)
|
280
280
|
try:
|
281
281
|
text_content = render_to_string(f"{template_name}.txt", context)
|
282
282
|
except:
|
283
283
|
text_content = strip_tags(html_content)
|
284
|
-
|
284
|
+
|
285
285
|
elif html_message:
|
286
286
|
# HTML email
|
287
287
|
html_content = html_message
|
288
288
|
text_content = message or strip_tags(html_message)
|
289
|
-
|
289
|
+
|
290
290
|
elif message:
|
291
291
|
# Simple text email
|
292
292
|
text_content = message
|
293
|
-
|
293
|
+
|
294
294
|
else:
|
295
295
|
raise ValueError("Must provide either message, html_message, or template_name")
|
296
|
-
|
296
|
+
|
297
297
|
return self.send_multipart(
|
298
298
|
subject=subject,
|
299
299
|
recipient_list=recipient_list,
|
@@ -303,78 +303,78 @@ class DjangoEmailService(BaseCfgModule):
|
|
303
303
|
attachments=attachments,
|
304
304
|
fail_silently=fail_silently,
|
305
305
|
)
|
306
|
-
|
306
|
+
|
307
307
|
def _prepare_template_context(self, context: Dict[str, Any], email_log_id: Optional[str] = None) -> Dict[str, Any]:
|
308
308
|
"""
|
309
309
|
Prepare template context with auto-added values from config.
|
310
|
-
|
310
|
+
|
311
311
|
Args:
|
312
312
|
context: Original context dictionary
|
313
313
|
email_log_id: Optional email log ID for tracking
|
314
|
-
|
314
|
+
|
315
315
|
Returns:
|
316
316
|
Updated context with auto-added values
|
317
317
|
"""
|
318
318
|
# Create a copy to avoid modifying the original
|
319
319
|
updated_context = context.copy()
|
320
|
-
|
320
|
+
|
321
321
|
# Auto-add project_name from config if not provided
|
322
322
|
if 'project_name' not in updated_context:
|
323
323
|
updated_context['project_name'] = self.config.project_name
|
324
|
-
|
324
|
+
|
325
325
|
# Auto-add logo_url from config if not provided
|
326
326
|
if 'logo_url' not in updated_context and self.config.project_logo:
|
327
327
|
updated_context['logo_url'] = self.config.project_logo
|
328
|
-
|
328
|
+
|
329
329
|
# Auto-add site_url from config if not provided
|
330
330
|
if 'site_url' not in updated_context:
|
331
331
|
updated_context['site_url'] = self.config.site_url
|
332
|
-
|
332
|
+
|
333
333
|
# Add tracking URLs if email_log_id is provided
|
334
334
|
if email_log_id:
|
335
335
|
base_url = self.config.api_url.rstrip('/')
|
336
336
|
updated_context['tracking_pixel_url'] = f"{base_url}/cfg/newsletter/track/open/{email_log_id}/"
|
337
337
|
updated_context['tracking_click_url'] = f"{base_url}/cfg/newsletter/track/click/{email_log_id}"
|
338
|
-
|
338
|
+
|
339
339
|
return updated_context
|
340
|
-
|
340
|
+
|
341
341
|
def _get_default_from_email(self) -> str:
|
342
342
|
"""Get the default from email address."""
|
343
|
-
if self.email_config and self.email_config.
|
344
|
-
return self.email_config.
|
345
|
-
|
343
|
+
if self.email_config and self.email_config.default_from:
|
344
|
+
return self.email_config.default_from
|
345
|
+
|
346
346
|
# Fallback to Django settings
|
347
347
|
return getattr(settings, 'DEFAULT_FROM_EMAIL', 'webmaster@localhost')
|
348
|
-
|
348
|
+
|
349
349
|
def _get_formatted_from_email(self, from_email: Optional[str] = None) -> str:
|
350
350
|
"""
|
351
351
|
Get formatted from email with project name.
|
352
|
-
|
352
|
+
|
353
353
|
Args:
|
354
354
|
from_email: Optional custom from email
|
355
|
-
|
355
|
+
|
356
356
|
Returns:
|
357
357
|
Formatted email in format: "Project Name <email@example.com>"
|
358
358
|
"""
|
359
359
|
if from_email is None:
|
360
360
|
from_email = self._get_default_from_email()
|
361
|
-
|
361
|
+
|
362
362
|
# If email already contains name (has < and >), return as is
|
363
363
|
if '<' in from_email and '>' in from_email:
|
364
364
|
return from_email
|
365
|
-
|
365
|
+
|
366
366
|
# Format with project name
|
367
367
|
project_name = self.config.project_name
|
368
368
|
return f'"{project_name}" <{from_email}>'
|
369
|
-
|
369
|
+
|
370
370
|
def is_configured(self) -> bool:
|
371
371
|
"""Check if email is properly configured."""
|
372
372
|
return self.email_config is not None and bool(self.email_config.host)
|
373
|
-
|
373
|
+
|
374
374
|
def get_backend_info(self) -> Dict[str, Any]:
|
375
375
|
"""Get information about the current email backend."""
|
376
376
|
backend = getattr(settings, 'EMAIL_BACKEND', 'django.core.mail.backends.smtp.EmailBackend')
|
377
|
-
|
377
|
+
|
378
378
|
info = {
|
379
379
|
'backend': backend,
|
380
380
|
'configured': self.is_configured(),
|
@@ -383,25 +383,25 @@ class DjangoEmailService(BaseCfgModule):
|
|
383
383
|
'use_tls': getattr(settings, 'EMAIL_USE_TLS', False),
|
384
384
|
'use_ssl': getattr(settings, 'EMAIL_USE_SSL', False),
|
385
385
|
}
|
386
|
-
|
386
|
+
|
387
387
|
if self.email_config:
|
388
388
|
info.update({
|
389
|
-
'default_from_email': self.email_config.
|
389
|
+
'default_from_email': self.email_config.default_from,
|
390
390
|
'default_from_name': getattr(self.email_config, 'default_from_name', None),
|
391
391
|
})
|
392
|
-
|
392
|
+
|
393
393
|
return info
|
394
|
-
|
394
|
+
|
395
395
|
# Backward compatibility aliases
|
396
|
-
def send_html_with_attachments(self, subject: str, html_message: str, recipient_list: List[str],
|
397
|
-
attachments: List[tuple], text_message: Optional[str] = None,
|
396
|
+
def send_html_with_attachments(self, subject: str, html_message: str, recipient_list: List[str],
|
397
|
+
attachments: List[tuple], text_message: Optional[str] = None,
|
398
398
|
from_email: Optional[str] = None, fail_silently: bool = False) -> bool:
|
399
399
|
"""Alias for send_with_attachments with HTML message."""
|
400
400
|
return self.send_with_attachments(
|
401
401
|
subject=subject, recipient_list=recipient_list, attachments=attachments,
|
402
402
|
html_message=html_message, message=text_message, from_email=from_email, fail_silently=fail_silently
|
403
403
|
)
|
404
|
-
|
404
|
+
|
405
405
|
def send_template_with_attachments(self, subject: str, template_name: str, context: Dict[str, Any],
|
406
406
|
recipient_list: List[str], attachments: List[tuple],
|
407
407
|
from_email: Optional[str] = None, fail_silently: bool = False) -> bool:
|
@@ -410,7 +410,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
410
410
|
subject=subject, recipient_list=recipient_list, attachments=attachments,
|
411
411
|
template_name=template_name, context=context, from_email=from_email, fail_silently=fail_silently
|
412
412
|
)
|
413
|
-
|
413
|
+
|
414
414
|
def send_template_with_tracking(
|
415
415
|
self,
|
416
416
|
subject: str,
|
@@ -423,7 +423,7 @@ class DjangoEmailService(BaseCfgModule):
|
|
423
423
|
) -> int:
|
424
424
|
"""
|
425
425
|
Send an email using a Django template with tracking support.
|
426
|
-
|
426
|
+
|
427
427
|
Args:
|
428
428
|
subject: Email subject
|
429
429
|
template_name: Template name (without .html extension)
|
@@ -432,24 +432,24 @@ class DjangoEmailService(BaseCfgModule):
|
|
432
432
|
email_log_id: Email log ID for tracking
|
433
433
|
from_email: Sender email (auto-detected if not provided)
|
434
434
|
fail_silently: Whether to fail silently on errors
|
435
|
-
|
435
|
+
|
436
436
|
Returns:
|
437
437
|
Number of emails sent successfully
|
438
438
|
"""
|
439
439
|
from_email = self._get_formatted_from_email(from_email)
|
440
|
-
|
440
|
+
|
441
441
|
# Prepare context with auto-added values and tracking
|
442
442
|
context = self._prepare_template_context(context, email_log_id)
|
443
|
-
|
443
|
+
|
444
444
|
# Render HTML template
|
445
445
|
html_message = render_to_string(f"{template_name}.html", context)
|
446
|
-
|
446
|
+
|
447
447
|
# Try to render plain text template
|
448
448
|
try:
|
449
449
|
text_message = render_to_string(f"{template_name}.txt", context)
|
450
450
|
except:
|
451
451
|
text_message = strip_tags(html_message)
|
452
|
-
|
452
|
+
|
453
453
|
return self.send_html(
|
454
454
|
subject=subject,
|
455
455
|
html_message=html_message,
|
@@ -460,39 +460,4 @@ class DjangoEmailService(BaseCfgModule):
|
|
460
460
|
)
|
461
461
|
|
462
462
|
|
463
|
-
|
464
|
-
def send_email(
|
465
|
-
subject: str,
|
466
|
-
message: str,
|
467
|
-
recipient_list: List[str],
|
468
|
-
from_email: Optional[str] = None,
|
469
|
-
fail_silently: bool = False,
|
470
|
-
) -> int:
|
471
|
-
"""
|
472
|
-
Send a simple email using auto-configured service.
|
473
|
-
|
474
|
-
Args:
|
475
|
-
subject: Email subject
|
476
|
-
message: Email message
|
477
|
-
recipient_list: List of recipient email addresses
|
478
|
-
from_email: Sender email (auto-detected if not provided)
|
479
|
-
fail_silently: Whether to fail silently on errors
|
480
|
-
|
481
|
-
Returns:
|
482
|
-
Number of emails sent successfully
|
483
|
-
"""
|
484
|
-
email_service = DjangoEmailService()
|
485
|
-
return email_service.send_simple(
|
486
|
-
subject=subject,
|
487
|
-
message=message,
|
488
|
-
recipient_list=recipient_list,
|
489
|
-
from_email=from_email,
|
490
|
-
fail_silently=fail_silently,
|
491
|
-
)
|
492
|
-
|
493
|
-
|
494
|
-
# Export public API
|
495
|
-
__all__ = [
|
496
|
-
'DjangoEmailService',
|
497
|
-
'send_email'
|
498
|
-
]
|
463
|
+
__all__ = ["DjangoEmailService"]
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"""
|
2
|
+
Email utilities and convenience functions.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional
|
6
|
+
|
7
|
+
from .service import DjangoEmailService
|
8
|
+
|
9
|
+
|
10
|
+
def send_email(
|
11
|
+
subject: str,
|
12
|
+
message: str,
|
13
|
+
recipient_list: List[str],
|
14
|
+
from_email: Optional[str] = None,
|
15
|
+
fail_silently: bool = False,
|
16
|
+
) -> int:
|
17
|
+
"""
|
18
|
+
Send a simple email using auto-configured service.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
subject: Email subject
|
22
|
+
message: Email message
|
23
|
+
recipient_list: List of recipient email addresses
|
24
|
+
from_email: Sender email (auto-detected if not provided)
|
25
|
+
fail_silently: Whether to fail silently on errors
|
26
|
+
|
27
|
+
Returns:
|
28
|
+
Number of emails sent successfully
|
29
|
+
"""
|
30
|
+
email_service = DjangoEmailService()
|
31
|
+
return email_service.send_simple(
|
32
|
+
subject=subject,
|
33
|
+
message=message,
|
34
|
+
recipient_list=recipient_list,
|
35
|
+
from_email=from_email,
|
36
|
+
fail_silently=fail_silently,
|
37
|
+
)
|
38
|
+
|
39
|
+
|
40
|
+
__all__ = ["send_email"]
|
@@ -208,34 +208,36 @@ class HealthCheckView(View):
|
|
208
208
|
}
|
209
209
|
|
210
210
|
def _check_configuration(self) -> Dict[str, Any]:
|
211
|
-
"""Check Django
|
211
|
+
"""Check Django-CFG configuration."""
|
212
212
|
try:
|
213
|
-
from django_cfg import
|
214
|
-
|
215
|
-
|
216
|
-
|
213
|
+
from django_cfg.core.state import get_current_config
|
214
|
+
from django.conf import settings
|
215
|
+
|
216
|
+
config = get_current_config()
|
217
|
+
|
217
218
|
config_status = {
|
218
219
|
"status": "healthy",
|
219
|
-
"
|
220
|
-
"version": "1.
|
221
|
-
"
|
222
|
-
"
|
223
|
-
"
|
224
|
-
"debug": toolkit.debug
|
225
|
-
},
|
226
|
-
"features": {
|
227
|
-
"unfold": toolkit.unfold_enabled,
|
228
|
-
"revolution": toolkit.revolution_enabled,
|
229
|
-
"constance": toolkit.constance_enabled,
|
230
|
-
"logging": toolkit.logging_enabled
|
220
|
+
"django_cfg": {
|
221
|
+
"version": "1.3.13",
|
222
|
+
"debug": settings.DEBUG,
|
223
|
+
"environment": "development" if settings.DEBUG else "production",
|
224
|
+
"secret_key_length": len(settings.SECRET_KEY) if hasattr(settings, 'SECRET_KEY') else 0
|
231
225
|
}
|
232
226
|
}
|
233
|
-
|
227
|
+
|
228
|
+
# Add config info if available
|
229
|
+
if config:
|
230
|
+
config_status["django_cfg"].update({
|
231
|
+
"project_name": config.project_name if hasattr(config, 'project_name') else "Unknown",
|
232
|
+
"enable_accounts": config.enable_accounts if hasattr(config, 'enable_accounts') else False,
|
233
|
+
"enable_tasks": config.enable_tasks if hasattr(config, 'enable_tasks') else False,
|
234
|
+
})
|
235
|
+
|
234
236
|
# Validate configuration
|
235
|
-
if not
|
237
|
+
if not hasattr(settings, 'SECRET_KEY') or len(settings.SECRET_KEY) < 50:
|
236
238
|
config_status["status"] = "warning"
|
237
|
-
config_status["warnings"] = ["Secret key is too short"]
|
238
|
-
|
239
|
+
config_status["warnings"] = ["Secret key is too short or not set"]
|
240
|
+
|
239
241
|
return config_status
|
240
242
|
|
241
243
|
except Exception as e:
|