django-cfg 1.4.21__py3-none-any.whl → 1.4.23__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 +4 -4
- django_cfg/apps/accounts/__init__.py +1 -1
- django_cfg/apps/accounts/__models.py +30 -29
- django_cfg/apps/accounts/admin/__init__.py +14 -3
- django_cfg/apps/accounts/admin/activity_admin.py +19 -19
- django_cfg/apps/accounts/admin/filters.py +7 -6
- django_cfg/apps/accounts/admin/group_admin.py +10 -16
- django_cfg/apps/accounts/admin/inlines.py +21 -19
- django_cfg/apps/accounts/admin/otp_admin.py +12 -12
- django_cfg/apps/accounts/admin/registration_admin.py +24 -24
- django_cfg/apps/accounts/admin/resources.py +49 -48
- django_cfg/apps/accounts/admin/twilio_admin.py +37 -37
- django_cfg/apps/accounts/admin/user_admin.py +45 -41
- django_cfg/apps/accounts/management/commands/otp_test.py +11 -11
- django_cfg/apps/accounts/managers/__init__.py +1 -1
- django_cfg/apps/accounts/managers/user_manager.py +6 -7
- django_cfg/apps/accounts/migrations/0001_initial.py +3 -2
- django_cfg/apps/accounts/models/__init__.py +15 -16
- django_cfg/apps/accounts/models/activity.py +5 -5
- django_cfg/apps/accounts/models/integrations.py +15 -15
- django_cfg/apps/accounts/models/registration.py +3 -2
- django_cfg/apps/accounts/models/user.py +3 -2
- django_cfg/apps/accounts/serializers/__init__.py +10 -3
- django_cfg/apps/accounts/serializers/otp.py +5 -4
- django_cfg/apps/accounts/serializers/profile.py +4 -5
- django_cfg/apps/accounts/serializers/webhook.py +13 -13
- django_cfg/apps/accounts/services/activity_service.py +13 -12
- django_cfg/apps/accounts/services/otp_service.py +16 -14
- django_cfg/apps/accounts/signals.py +18 -16
- django_cfg/apps/accounts/urls.py +10 -5
- django_cfg/apps/accounts/utils/notifications.py +22 -22
- django_cfg/apps/accounts/views/__init__.py +1 -1
- django_cfg/apps/accounts/views/otp.py +15 -14
- django_cfg/apps/accounts/views/profile.py +14 -10
- django_cfg/apps/accounts/views/webhook.py +46 -48
- django_cfg/apps/agents/__init__.py +3 -3
- django_cfg/apps/agents/admin/__init__.py +1 -1
- django_cfg/apps/agents/admin/execution_admin.py +68 -72
- django_cfg/apps/agents/admin/registry_admin.py +50 -54
- django_cfg/apps/agents/admin/toolsets_admin.py +63 -67
- django_cfg/apps/agents/apps.py +3 -3
- django_cfg/apps/agents/core/__init__.py +4 -4
- django_cfg/apps/agents/core/dependencies.py +24 -23
- django_cfg/apps/agents/core/django_agent.py +41 -39
- django_cfg/apps/agents/core/exceptions.py +12 -12
- django_cfg/apps/agents/core/models.py +16 -15
- django_cfg/apps/agents/core/orchestrator.py +58 -58
- django_cfg/apps/agents/examples/simple_example.py +24 -19
- django_cfg/apps/agents/integration/__init__.py +1 -1
- django_cfg/apps/agents/integration/middleware.py +12 -11
- django_cfg/apps/agents/integration/registry.py +52 -49
- django_cfg/apps/agents/integration/signals.py +5 -5
- django_cfg/apps/agents/management/commands/create_agent.py +39 -38
- django_cfg/apps/agents/management/commands/orchestrator_status.py +40 -39
- django_cfg/apps/agents/managers/__init__.py +8 -3
- django_cfg/apps/agents/managers/execution.py +42 -41
- django_cfg/apps/agents/managers/registry.py +40 -39
- django_cfg/apps/agents/managers/toolsets.py +87 -86
- django_cfg/apps/agents/migrations/0001_initial.py +2 -1
- django_cfg/apps/agents/models/__init__.py +2 -2
- django_cfg/apps/agents/models/execution.py +43 -42
- django_cfg/apps/agents/models/registry.py +46 -45
- django_cfg/apps/agents/models/toolsets.py +63 -62
- django_cfg/apps/agents/patterns/__init__.py +5 -5
- django_cfg/apps/agents/patterns/content_agents.py +17 -16
- django_cfg/apps/agents/toolsets/__init__.py +3 -3
- django_cfg/apps/agents/toolsets/cache_toolset.py +56 -55
- django_cfg/apps/agents/toolsets/django_toolset.py +43 -42
- django_cfg/apps/agents/toolsets/file_toolset.py +64 -63
- django_cfg/apps/agents/toolsets/orm_toolset.py +75 -74
- django_cfg/apps/agents/urls.py +3 -2
- django_cfg/apps/api/commands/urls.py +1 -0
- django_cfg/apps/api/commands/views.py +23 -26
- django_cfg/apps/api/endpoints/checker.py +5 -4
- django_cfg/apps/api/endpoints/drf_views.py +2 -2
- django_cfg/apps/api/endpoints/tests.py +6 -5
- django_cfg/apps/api/endpoints/urls.py +2 -1
- django_cfg/apps/api/endpoints/views.py +1 -0
- django_cfg/apps/api/health/drf_views.py +6 -6
- django_cfg/apps/api/health/urls.py +2 -1
- django_cfg/apps/api/health/views.py +41 -41
- django_cfg/{modules/django_ipc_client → apps/ipc}/__init__.py +6 -6
- django_cfg/apps/ipc/apps.py +28 -0
- django_cfg/apps/ipc/serializers/__init__.py +19 -0
- django_cfg/apps/ipc/serializers/serializers.py +229 -0
- django_cfg/apps/ipc/services/__init__.py +7 -0
- django_cfg/apps/ipc/services/client/__init__.py +23 -0
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/client.py +7 -6
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/exceptions.py +1 -1
- django_cfg/{modules/django_ipc_client/dashboard → apps/ipc/services}/monitor.py +23 -5
- django_cfg/{modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js → apps/ipc/static/django_cfg_ipc/js/dashboard.mjs} +131 -63
- django_cfg/{modules/django_ipc_client/dashboard/templates/django_ipc_dashboard → apps/ipc/templates/django_cfg_ipc}/base.html +5 -10
- django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +202 -0
- django_cfg/apps/ipc/urls.py +21 -0
- django_cfg/apps/ipc/urls_admin.py +20 -0
- django_cfg/apps/ipc/views/__init__.py +8 -0
- django_cfg/apps/ipc/views/dashboard.py +15 -0
- django_cfg/apps/ipc/views/viewsets.py +245 -0
- django_cfg/apps/knowbase/admin/__init__.py +2 -2
- django_cfg/apps/knowbase/admin/actions/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +2 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +81 -84
- django_cfg/apps/knowbase/admin/chat_admin.py +70 -72
- django_cfg/apps/knowbase/admin/document_admin.py +10 -11
- django_cfg/apps/knowbase/admin/external_data_admin.py +69 -71
- django_cfg/apps/knowbase/admin/helpers/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/helpers/configs.py +2 -2
- django_cfg/apps/knowbase/admin/helpers/statistics.py +1 -1
- django_cfg/apps/knowbase/apps.py +13 -13
- django_cfg/apps/knowbase/config/__init__.py +7 -6
- django_cfg/apps/knowbase/config/constance_fields.py +14 -12
- django_cfg/apps/knowbase/config/constance_settings.py +32 -31
- django_cfg/apps/knowbase/config/settings.py +28 -28
- django_cfg/apps/knowbase/examples/external_data_usage.py +35 -32
- django_cfg/apps/knowbase/management/commands/knowbase_stats.py +33 -32
- django_cfg/apps/knowbase/management/commands/setup_knowbase.py +11 -13
- django_cfg/apps/knowbase/managers/__init__.py +2 -2
- django_cfg/apps/knowbase/managers/archive.py +86 -85
- django_cfg/apps/knowbase/managers/base.py +5 -5
- django_cfg/apps/knowbase/managers/chat.py +29 -28
- django_cfg/apps/knowbase/managers/document.py +39 -39
- django_cfg/apps/knowbase/managers/external_data.py +74 -73
- django_cfg/apps/knowbase/migrations/0001_initial.py +2 -1
- django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +2 -1
- django_cfg/apps/knowbase/mixins/__init__.py +4 -4
- django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
- django_cfg/apps/knowbase/mixins/config.py +19 -18
- django_cfg/apps/knowbase/mixins/creator.py +7 -7
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
- django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
- django_cfg/apps/knowbase/mixins/service.py +47 -45
- django_cfg/apps/knowbase/models/__init__.py +7 -7
- django_cfg/apps/knowbase/models/archive.py +72 -72
- django_cfg/apps/knowbase/models/base.py +12 -13
- django_cfg/apps/knowbase/models/chat.py +20 -19
- django_cfg/apps/knowbase/models/document.py +37 -35
- django_cfg/apps/knowbase/models/external_data.py +41 -42
- django_cfg/apps/knowbase/serializers/__init__.py +7 -7
- django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
- django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
- django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
- django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
- django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
- django_cfg/apps/knowbase/services/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
- django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
- django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
- django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
- django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
- django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
- django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
- django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
- django_cfg/apps/knowbase/services/base.py +11 -9
- django_cfg/apps/knowbase/services/chat_service.py +40 -39
- django_cfg/apps/knowbase/services/document_service.py +28 -27
- django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
- django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
- django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
- django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
- django_cfg/apps/knowbase/services/embedding/models.py +52 -51
- django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
- django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
- django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
- django_cfg/apps/knowbase/services/search_service.py +52 -49
- django_cfg/apps/knowbase/signals/__init__.py +2 -5
- django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
- django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
- django_cfg/apps/knowbase/signals/document_signals.py +22 -22
- django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
- django_cfg/apps/knowbase/tasks/__init__.py +6 -7
- django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
- django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
- django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
- django_cfg/apps/knowbase/urls.py +3 -2
- django_cfg/apps/knowbase/urls_admin.py +6 -3
- django_cfg/apps/knowbase/urls_system.py +4 -5
- django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
- django_cfg/apps/knowbase/utils/text_processing.py +76 -75
- django_cfg/apps/knowbase/utils/validation.py +9 -9
- django_cfg/apps/knowbase/views/__init__.py +5 -5
- django_cfg/apps/knowbase/views/archive_views.py +90 -87
- django_cfg/apps/knowbase/views/base.py +9 -12
- django_cfg/apps/knowbase/views/chat_views.py +32 -32
- django_cfg/apps/knowbase/views/document_views.py +27 -28
- django_cfg/apps/knowbase/views/public_views.py +19 -19
- django_cfg/apps/leads/admin/leads_admin.py +41 -45
- django_cfg/apps/leads/admin/resources.py +14 -14
- django_cfg/apps/leads/admin.py +7 -9
- django_cfg/apps/leads/apps.py +1 -1
- django_cfg/apps/leads/models.py +17 -17
- django_cfg/apps/leads/serializers.py +5 -4
- django_cfg/apps/leads/signals.py +7 -7
- django_cfg/apps/leads/tests.py +47 -47
- django_cfg/apps/leads/urls.py +2 -2
- django_cfg/apps/leads/views.py +11 -11
- django_cfg/apps/maintenance/__init__.py +3 -3
- django_cfg/apps/maintenance/admin/__init__.py +1 -1
- django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
- django_cfg/apps/maintenance/admin/log_admin.py +35 -37
- django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
- django_cfg/apps/maintenance/admin/site_admin.py +49 -52
- django_cfg/apps/maintenance/apps.py +2 -2
- django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
- django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
- django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
- django_cfg/apps/maintenance/managers/__init__.py +1 -1
- django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
- django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
- django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
- django_cfg/apps/maintenance/models/__init__.py +2 -2
- django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
- django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
- django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
- django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
- django_cfg/apps/maintenance/services/__init__.py +3 -3
- django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
- django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
- django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
- django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
- django_cfg/apps/maintenance/utils/__init__.py +1 -1
- django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
- django_cfg/apps/newsletter/admin/__init__.py +12 -16
- django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
- django_cfg/apps/newsletter/admin/resources.py +29 -29
- django_cfg/apps/newsletter/admin.py +39 -32
- django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
- django_cfg/apps/newsletter/managers/__init__.py +1 -1
- django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
- django_cfg/apps/newsletter/models.py +34 -33
- django_cfg/apps/newsletter/serializers.py +13 -13
- django_cfg/apps/newsletter/services/email_service.py +42 -40
- django_cfg/apps/newsletter/signals.py +4 -3
- django_cfg/apps/newsletter/urls.py +7 -7
- django_cfg/apps/newsletter/views/__init__.py +14 -19
- django_cfg/apps/newsletter/views/campaigns.py +19 -19
- django_cfg/apps/newsletter/views/emails.py +20 -20
- django_cfg/apps/newsletter/views/newsletters.py +5 -5
- django_cfg/apps/newsletter/views/subscriptions.py +24 -24
- django_cfg/apps/newsletter/views/tracking.py +6 -5
- django_cfg/apps/payments/admin/__init__.py +6 -5
- django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
- django_cfg/apps/payments/admin/balance_admin.py +41 -47
- django_cfg/apps/payments/admin/currencies_admin.py +60 -62
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
- django_cfg/apps/payments/admin/filters.py +59 -59
- django_cfg/apps/payments/admin/networks_admin.py +36 -50
- django_cfg/apps/payments/admin/payments_admin.py +47 -49
- django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
- django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
- django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
- django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
- django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
- django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
- django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
- django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
- django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
- django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
- django_cfg/apps/payments/admin_interface/views/base.py +17 -19
- django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
- django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
- django_cfg/apps/payments/apps.py +7 -6
- django_cfg/apps/payments/config/__init__.py +4 -4
- django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
- django_cfg/apps/payments/config/helpers.py +14 -12
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
- django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
- django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
- django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
- django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
- django_cfg/apps/payments/management/commands/test_providers.py +83 -84
- django_cfg/apps/payments/middleware/__init__.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +77 -78
- django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
- django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
- django_cfg/apps/payments/migrations/0001_initial.py +2 -1
- django_cfg/apps/payments/models/__init__.py +11 -12
- django_cfg/apps/payments/models/api_keys.py +29 -27
- django_cfg/apps/payments/models/balance.py +38 -38
- django_cfg/apps/payments/models/base.py +12 -11
- django_cfg/apps/payments/models/currencies.py +53 -52
- django_cfg/apps/payments/models/managers/__init__.py +13 -14
- django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
- django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
- django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
- django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
- django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
- django_cfg/apps/payments/models/payments.py +167 -73
- django_cfg/apps/payments/models/subscriptions.py +56 -54
- django_cfg/apps/payments/models/tariffs.py +35 -34
- django_cfg/apps/payments/services/__init__.py +33 -36
- django_cfg/apps/payments/services/cache/__init__.py +7 -1
- django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
- django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
- django_cfg/apps/payments/services/cache_service/keys.py +8 -8
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
- django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
- django_cfg/apps/payments/services/core/__init__.py +3 -3
- django_cfg/apps/payments/services/core/balance_service.py +69 -65
- django_cfg/apps/payments/services/core/base.py +25 -22
- django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
- django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
- django_cfg/apps/payments/services/core/currency_service.py +68 -66
- django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
- django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
- django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
- django_cfg/apps/payments/services/core/payment_service.py +10 -7
- django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
- django_cfg/apps/payments/services/core/subscription_service.py +77 -74
- django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
- django_cfg/apps/payments/services/core/webhook_service.py +67 -63
- django_cfg/apps/payments/services/integrations/__init__.py +3 -3
- django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
- django_cfg/apps/payments/services/providers/base.py +59 -57
- django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
- django_cfg/apps/payments/services/providers/models/base.py +15 -15
- django_cfg/apps/payments/services/providers/models/providers.py +13 -12
- django_cfg/apps/payments/services/providers/models/universal.py +6 -5
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
- django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
- django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
- django_cfg/apps/payments/services/providers/registry.py +65 -63
- django_cfg/apps/payments/services/providers/sync_service.py +50 -50
- django_cfg/apps/payments/services/types/__init__.py +21 -22
- django_cfg/apps/payments/services/types/data.py +14 -13
- django_cfg/apps/payments/services/types/requests.py +21 -22
- django_cfg/apps/payments/services/types/responses.py +16 -15
- django_cfg/apps/payments/services/types/webhooks.py +30 -30
- django_cfg/apps/payments/signals/__init__.py +4 -6
- django_cfg/apps/payments/signals/api_key_signals.py +33 -32
- django_cfg/apps/payments/signals/balance_signals.py +28 -26
- django_cfg/apps/payments/signals/payment_signals.py +29 -28
- django_cfg/apps/payments/signals/subscription_signals.py +39 -38
- django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
- django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
- django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
- django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
- django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
- django_cfg/apps/payments/tasks/__init__.py +11 -12
- django_cfg/apps/payments/tasks/types.py +10 -9
- django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
- django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
- django_cfg/apps/payments/urls.py +31 -14
- django_cfg/apps/payments/urls_admin.py +10 -10
- django_cfg/apps/payments/views/api/__init__.py +32 -33
- django_cfg/apps/payments/views/api/api_keys.py +62 -62
- django_cfg/apps/payments/views/api/balances.py +63 -64
- django_cfg/apps/payments/views/api/base.py +52 -52
- django_cfg/apps/payments/views/api/currencies.py +75 -63
- django_cfg/apps/payments/views/api/payments.py +73 -74
- django_cfg/apps/payments/views/api/subscriptions.py +71 -72
- django_cfg/apps/payments/views/api/webhooks.py +85 -84
- django_cfg/apps/payments/views/overview/__init__.py +7 -7
- django_cfg/apps/payments/views/overview/serializers.py +13 -14
- django_cfg/apps/payments/views/overview/services.py +66 -67
- django_cfg/apps/payments/views/overview/urls.py +2 -1
- django_cfg/apps/payments/views/overview/views.py +31 -31
- django_cfg/apps/payments/views/serializers/__init__.py +35 -36
- django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
- django_cfg/apps/payments/views/serializers/balances.py +34 -33
- django_cfg/apps/payments/views/serializers/currencies.py +36 -34
- django_cfg/apps/payments/views/serializers/payments.py +48 -47
- django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
- django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
- django_cfg/apps/support/admin/__init__.py +3 -3
- django_cfg/apps/support/admin/resources.py +26 -26
- django_cfg/apps/support/admin/support_admin.py +44 -48
- django_cfg/apps/support/admin.py +16 -15
- django_cfg/apps/support/apps.py +1 -1
- django_cfg/apps/support/managers/message_manager.py +4 -4
- django_cfg/apps/support/managers/ticket_manager.py +13 -12
- django_cfg/apps/support/migrations/0001_initial.py +2 -1
- django_cfg/apps/support/models.py +3 -1
- django_cfg/apps/support/serializers.py +4 -2
- django_cfg/apps/support/signals.py +12 -10
- django_cfg/apps/support/urls.py +4 -3
- django_cfg/apps/support/utils/support_email_service.py +11 -9
- django_cfg/apps/support/views/__init__.py +3 -3
- django_cfg/apps/support/views/admin.py +9 -9
- django_cfg/apps/support/views/api.py +10 -9
- django_cfg/apps/support/views/chat.py +14 -14
- django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
- django_cfg/apps/tasks/apps.py +2 -2
- django_cfg/apps/tasks/serializers.py +6 -6
- django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
- django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
- django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
- django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
- django_cfg/apps/tasks/urls.py +3 -2
- django_cfg/apps/tasks/urls_admin.py +1 -0
- django_cfg/apps/tasks/utils/simulator.py +49 -52
- django_cfg/apps/tasks/views/api.py +75 -73
- django_cfg/apps/tasks/views/dashboard.py +5 -4
- django_cfg/apps/urls.py +20 -11
- django_cfg/apps.py +6 -5
- django_cfg/cli/commands/create_project.py +7 -6
- django_cfg/cli/commands/info.py +25 -25
- django_cfg/cli/utils.py +27 -27
- django_cfg/config.py +1 -1
- django_cfg/core/__init__.py +8 -8
- django_cfg/core/base/config_model.py +13 -12
- django_cfg/core/builders/apps_builder.py +2 -2
- django_cfg/core/builders/middleware_builder.py +1 -1
- django_cfg/core/builders/security_builder.py +1 -1
- django_cfg/core/config.py +2 -2
- django_cfg/core/environment/detector.py +27 -28
- django_cfg/core/exceptions.py +1 -1
- django_cfg/core/generation/core_generators/settings.py +1 -1
- django_cfg/core/generation/core_generators/static.py +11 -5
- django_cfg/core/generation/core_generators/templates.py +1 -1
- django_cfg/core/generation/data_generators/__init__.py +1 -1
- django_cfg/core/generation/data_generators/cache.py +1 -1
- django_cfg/core/generation/data_generators/database.py +1 -1
- django_cfg/core/generation/generation.py +1 -3
- django_cfg/core/generation/integration_generators/__init__.py +2 -2
- django_cfg/core/generation/integration_generators/api.py +12 -2
- django_cfg/core/generation/integration_generators/sessions.py +1 -1
- django_cfg/core/generation/integration_generators/tailwind.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +1 -1
- django_cfg/core/generation/integration_generators/third_party.py +1 -1
- django_cfg/core/generation/orchestrator.py +1 -1
- django_cfg/core/generation/protocols.py +1 -1
- django_cfg/core/generation/utility_generators/__init__.py +1 -1
- django_cfg/core/generation/utility_generators/email.py +1 -1
- django_cfg/core/generation/utility_generators/i18n.py +1 -1
- django_cfg/core/generation/utility_generators/limits.py +1 -1
- django_cfg/core/generation/utility_generators/logging.py +1 -1
- django_cfg/core/generation/utility_generators/security.py +1 -1
- django_cfg/core/generation/utils/helpers.py +1 -1
- django_cfg/core/integration/__init__.py +5 -5
- django_cfg/core/integration/commands_collector.py +38 -39
- django_cfg/core/integration/display/__init__.py +2 -2
- django_cfg/core/integration/display/base.py +30 -30
- django_cfg/core/integration/display/ngrok.py +35 -36
- django_cfg/core/integration/display/startup.py +149 -139
- django_cfg/core/integration/url_integration.py +10 -10
- django_cfg/core/integration/version_checker.py +20 -19
- django_cfg/core/services/config_service.py +4 -4
- django_cfg/core/state/__init__.py +1 -1
- django_cfg/core/state/registry.py +1 -1
- django_cfg/core/types/__init__.py +8 -1
- django_cfg/core/validation.py +36 -39
- django_cfg/management/commands/check_endpoints.py +3 -1
- django_cfg/management/commands/check_settings.py +3 -1
- django_cfg/management/commands/clear_constance.py +3 -1
- django_cfg/management/commands/create_token.py +3 -1
- django_cfg/management/commands/generate_clients.py +3 -1
- django_cfg/management/commands/migrate_all.py +3 -1
- django_cfg/management/commands/rundramatiq.py +3 -1
- django_cfg/management/commands/rundramatiq_simulator.py +3 -1
- django_cfg/management/commands/runserver_ngrok.py +3 -1
- django_cfg/management/commands/show_config.py +3 -1
- django_cfg/management/commands/superuser.py +3 -1
- django_cfg/management/commands/task_clear.py +3 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -1
- django_cfg/management/commands/test_telegram.py +3 -1
- django_cfg/management/commands/test_twilio.py +3 -1
- django_cfg/management/commands/validate_openapi.py +3 -1
- django_cfg/middleware/pagination.py +8 -8
- django_cfg/middleware/public_endpoints.py +24 -23
- django_cfg/middleware/user_activity.py +27 -25
- django_cfg/models/__init__.py +19 -20
- django_cfg/models/api/__init__.py +4 -4
- django_cfg/models/api/config.py +23 -21
- django_cfg/models/api/cors.py +17 -16
- django_cfg/models/api/drf/__init__.py +1 -1
- django_cfg/models/api/drf/config.py +2 -1
- django_cfg/models/api/drf/redoc.py +2 -1
- django_cfg/models/api/drf/spectacular.py +4 -2
- django_cfg/models/api/drf/swagger.py +2 -1
- django_cfg/models/api/jwt.py +37 -36
- django_cfg/models/api/keys.py +13 -12
- django_cfg/models/api/limits.py +31 -30
- django_cfg/models/base/config.py +40 -41
- django_cfg/models/base/module.py +8 -8
- django_cfg/models/django/__init__.py +1 -1
- django_cfg/models/django/constance.py +8 -7
- django_cfg/models/django/environment.py +5 -3
- django_cfg/models/django/openapi.py +6 -16
- django_cfg/models/django/revolution_legacy.py +17 -16
- django_cfg/models/infrastructure/__init__.py +1 -1
- django_cfg/models/infrastructure/cache.py +46 -45
- django_cfg/models/infrastructure/database/config.py +4 -6
- django_cfg/models/infrastructure/database/converters.py +1 -1
- django_cfg/models/infrastructure/database/parsers.py +1 -1
- django_cfg/models/infrastructure/database/validators.py +1 -1
- django_cfg/models/infrastructure/logging.py +59 -57
- django_cfg/models/infrastructure/security.py +26 -24
- django_cfg/models/ngrok/auth.py +2 -1
- django_cfg/models/ngrok/config.py +3 -2
- django_cfg/models/ngrok/tunnel.py +2 -1
- django_cfg/models/payments/__init__.py +1 -1
- django_cfg/models/payments/api_keys.py +3 -1
- django_cfg/models/payments/config.py +4 -1
- django_cfg/models/payments/providers/base.py +2 -1
- django_cfg/models/payments/providers/nowpayments.py +3 -1
- django_cfg/models/services/__init__.py +1 -1
- django_cfg/models/services/base.py +2 -1
- django_cfg/models/services/email.py +28 -26
- django_cfg/models/services/telegram.py +2 -1
- django_cfg/models/tasks/__init__.py +2 -2
- django_cfg/models/tasks/backends.py +4 -3
- django_cfg/models/tasks/config.py +6 -4
- django_cfg/models/tasks/utils.py +3 -3
- django_cfg/modules/base.py +18 -17
- django_cfg/modules/django_admin/__init__.py +14 -15
- django_cfg/modules/django_admin/decorators/__init__.py +1 -1
- django_cfg/modules/django_admin/decorators/actions.py +8 -7
- django_cfg/modules/django_admin/decorators/display.py +9 -7
- django_cfg/modules/django_admin/icons/__init__.py +1 -1
- django_cfg/modules/django_admin/icons/constants.py +27 -27
- django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
- django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
- django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
- django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
- django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
- django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
- django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
- django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
- django_cfg/modules/django_admin/management/commands/script.py +58 -60
- django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
- django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
- django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
- django_cfg/modules/django_admin/management/commands/tree.py +50 -54
- django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
- django_cfg/modules/django_admin/models/__init__.py +4 -4
- django_cfg/modules/django_admin/models/action_models.py +3 -1
- django_cfg/modules/django_admin/models/badge_models.py +4 -2
- django_cfg/modules/django_admin/models/base.py +3 -3
- django_cfg/modules/django_admin/models/display_models.py +1 -0
- django_cfg/modules/django_admin/utils/badges.py +27 -26
- django_cfg/modules/django_admin/utils/displays.py +49 -49
- django_cfg/modules/django_client/apps.py +21 -3
- django_cfg/modules/django_client/core/__init__.py +9 -10
- django_cfg/modules/django_client/core/archive/manager.py +2 -2
- django_cfg/modules/django_client/core/cli/main.py +1 -3
- django_cfg/modules/django_client/core/config/config.py +3 -1
- django_cfg/modules/django_client/core/config/group.py +1 -0
- django_cfg/modules/django_client/core/config/service.py +2 -1
- django_cfg/modules/django_client/core/generator/__init__.py +1 -1
- django_cfg/modules/django_client/core/generator/base.py +2 -2
- django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
- django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
- django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
- django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
- django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
- django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
- django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
- django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
- django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
- django_cfg/modules/django_client/core/groups/__init__.py +1 -1
- django_cfg/modules/django_client/core/groups/detector.py +2 -1
- django_cfg/modules/django_client/core/groups/manager.py +2 -1
- django_cfg/modules/django_client/core/ir/schema.py +1 -1
- django_cfg/modules/django_client/core/parser/base.py +0 -2
- django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
- django_cfg/modules/django_client/core/validation/__init__.py +1 -1
- django_cfg/modules/django_client/core/validation/fixer.py +1 -2
- django_cfg/modules/django_client/core/validation/reporter.py +2 -2
- django_cfg/modules/django_client/core/validation/safety.py +1 -1
- django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
- django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
- django_cfg/modules/django_client/spectacular/__init__.py +1 -1
- django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
- django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
- django_cfg/modules/django_client/spectacular/schema.py +5 -5
- django_cfg/modules/django_client/system/__init__.py +24 -0
- django_cfg/modules/django_client/system/base_generator.py +123 -0
- django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
- django_cfg/modules/django_client/system/mjs_generator.py +219 -0
- django_cfg/modules/django_client/system/schema_parser.py +195 -0
- django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
- django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
- django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
- django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
- django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
- django_cfg/modules/django_client/urls.py +3 -2
- django_cfg/modules/django_currency/__init__.py +17 -18
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
- django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
- django_cfg/modules/django_currency/core/__init__.py +7 -13
- django_cfg/modules/django_currency/core/converter.py +25 -24
- django_cfg/modules/django_currency/core/models.py +9 -8
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +65 -66
- django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
- django_cfg/modules/django_currency/utils/cache.py +10 -11
- django_cfg/modules/django_dashboard/__init__.py +4 -5
- django_cfg/modules/django_dashboard/components.py +11 -7
- django_cfg/modules/django_dashboard/debug.py +1 -3
- django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
- django_cfg/modules/django_dashboard/sections/base.py +2 -1
- django_cfg/modules/django_dashboard/sections/commands.py +3 -2
- django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
- django_cfg/modules/django_dashboard/sections/overview.py +13 -9
- django_cfg/modules/django_dashboard/sections/stats.py +2 -2
- django_cfg/modules/django_dashboard/sections/system.py +2 -1
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
- django_cfg/modules/django_email/management/commands/test_email.py +8 -7
- django_cfg/modules/django_email/service.py +5 -4
- django_cfg/modules/django_health/service.py +46 -44
- django_cfg/modules/django_import_export/__init__.py +7 -3
- django_cfg/modules/django_llm/__init__.py +3 -2
- django_cfg/modules/django_llm/example.py +58 -56
- django_cfg/modules/django_llm/llm/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/cache.py +21 -20
- django_cfg/modules/django_llm/llm/client.py +9 -9
- django_cfg/modules/django_llm/llm/costs.py +14 -14
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/extractor.py +8 -8
- django_cfg/modules/django_llm/llm/models.py +5 -5
- django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
- django_cfg/modules/django_llm/llm/models_cache.py +91 -92
- django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
- django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
- django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
- django_cfg/modules/django_llm/translator/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/cache.py +36 -35
- django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
- django_cfg/modules/django_llm/translator/translator.py +5 -4
- django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
- django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
- django_cfg/modules/django_logging/__init__.py +1 -1
- django_cfg/modules/django_logging/django_logger.py +33 -34
- django_cfg/modules/django_logging/logger.py +3 -7
- django_cfg/modules/django_ngrok/__init__.py +7 -7
- django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
- django_cfg/modules/django_ngrok/service.py +33 -32
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
- django_cfg/modules/django_tasks/__init__.py +5 -5
- django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
- django_cfg/modules/django_tasks/factory.py +1 -1
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
- django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
- django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
- django_cfg/modules/django_tasks/service.py +4 -3
- django_cfg/modules/django_tasks/settings.py +1 -1
- django_cfg/modules/django_telegram/__init__.py +4 -4
- django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
- django_cfg/modules/django_telegram/service.py +4 -3
- django_cfg/modules/django_telegram/utils.py +1 -1
- django_cfg/modules/django_twilio/__init__.py +15 -16
- django_cfg/modules/django_twilio/_imports.py +1 -1
- django_cfg/modules/django_twilio/base.py +9 -5
- django_cfg/modules/django_twilio/email_otp.py +4 -3
- django_cfg/modules/django_twilio/exceptions.py +36 -36
- django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
- django_cfg/modules/django_twilio/models.py +54 -53
- django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
- django_cfg/modules/django_twilio/simple_service.py +42 -41
- django_cfg/modules/django_twilio/sms.py +1 -0
- django_cfg/modules/django_twilio/twilio_service.py +79 -83
- django_cfg/modules/django_twilio/unified.py +6 -5
- django_cfg/modules/django_twilio/utils.py +2 -3
- django_cfg/modules/django_twilio/whatsapp.py +3 -2
- django_cfg/modules/django_unfold/__init__.py +7 -6
- django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
- django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
- django_cfg/modules/django_unfold/callbacks/base.py +9 -8
- django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
- django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
- django_cfg/modules/django_unfold/callbacks/main.py +27 -27
- django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
- django_cfg/modules/django_unfold/callbacks/system.py +5 -5
- django_cfg/modules/django_unfold/callbacks/users.py +4 -4
- django_cfg/modules/django_unfold/dashboard.py +29 -29
- django_cfg/modules/django_unfold/models/__init__.py +23 -8
- django_cfg/modules/django_unfold/models/config.py +84 -81
- django_cfg/modules/django_unfold/models/dashboard.py +20 -19
- django_cfg/modules/django_unfold/models/dropdown.py +6 -4
- django_cfg/modules/django_unfold/models/navigation.py +6 -4
- django_cfg/modules/django_unfold/models/tabs.py +4 -3
- django_cfg/modules/django_unfold/models.py +2 -3
- django_cfg/modules/django_unfold/system_monitor.py +27 -25
- django_cfg/modules/django_unfold/tailwind.py +12 -14
- django_cfg/modules/django_unfold/utils.py +7 -6
- django_cfg/pyproject.toml +1 -1
- django_cfg/registry/__init__.py +3 -3
- django_cfg/registry/core.py +8 -8
- django_cfg/registry/modules.py +2 -2
- django_cfg/registry/services.py +2 -2
- django_cfg/registry/third_party.py +3 -3
- django_cfg/routing/__init__.py +3 -3
- django_cfg/routing/callbacks.py +27 -26
- django_cfg/routing/routers.py +2 -2
- django_cfg/static/js/api/accounts/client.mjs +69 -0
- django_cfg/static/js/api/accounts/index.mjs +13 -0
- django_cfg/static/js/api/base.mjs +166 -0
- django_cfg/static/js/api/index.mjs +100 -0
- django_cfg/static/js/api/ipc/client.mjs +74 -0
- django_cfg/static/js/api/ipc/index.mjs +13 -0
- django_cfg/static/js/api/leads/client.mjs +71 -0
- django_cfg/static/js/api/leads/index.mjs +13 -0
- django_cfg/static/js/api/newsletter/client.mjs +109 -0
- django_cfg/static/js/api/newsletter/index.mjs +13 -0
- django_cfg/static/js/api/payments/client.mjs +1264 -0
- django_cfg/static/js/api/payments/index.mjs +13 -0
- django_cfg/static/js/api/support/client.mjs +84 -0
- django_cfg/static/js/api/support/index.mjs +13 -0
- django_cfg/static/js/api/tasks/client.mjs +74 -0
- django_cfg/static/js/api/tasks/index.mjs +13 -0
- django_cfg/static/js/api/types.mjs +729 -0
- django_cfg/static/js/api-loader.mjs +169 -0
- django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
- django_cfg/templatetags/django_cfg.py +4 -4
- django_cfg/utils/path_resolution.py +49 -50
- django_cfg/utils/smart_defaults.py +27 -29
- django_cfg/utils/version_check.py +14 -14
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/METADATA +1 -1
- django_cfg-1.4.23.dist-info/RECORD +1137 -0
- django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
- django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
- django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
- django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
- django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
- django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
- django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
- django_cfg/modules/django_rpc_old/POETRY.md +0 -344
- django_cfg/modules/django_rpc_old/README.md +0 -397
- django_cfg/modules/django_rpc_old/TESTING.md +0 -358
- django_cfg/modules/django_rpc_old/__init__.py +0 -39
- django_cfg/modules/django_rpc_old/client.py +0 -531
- django_cfg/modules/django_rpc_old/config.py +0 -279
- django_cfg/modules/django_rpc_old/exceptions.py +0 -172
- django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
- django_cfg-1.4.21.dist-info/RECORD +0 -1111
- /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
- /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -4,24 +4,21 @@ CloudflareSite admin using Django Admin Utilities.
|
|
4
4
|
Enhanced site management with Material Icons and optimized queries.
|
5
5
|
"""
|
6
6
|
|
7
|
+
|
7
8
|
from django.contrib import admin, messages
|
8
|
-
from django.urls import reverse
|
9
|
-
from django.http import HttpRequest
|
10
|
-
from django.shortcuts import redirect
|
11
|
-
from django.db import models
|
12
9
|
from django.db.models import Count, Q
|
13
|
-
from
|
10
|
+
from django.http import HttpRequest
|
14
11
|
from unfold.admin import ModelAdmin, TabularInline
|
15
12
|
|
16
13
|
from django_cfg.modules.django_admin import (
|
17
|
-
|
18
|
-
DisplayMixin,
|
19
|
-
StatusBadgeConfig,
|
14
|
+
ActionVariant,
|
20
15
|
DateTimeDisplayConfig,
|
16
|
+
DisplayMixin,
|
21
17
|
Icons,
|
22
|
-
|
18
|
+
OptimizedModelAdmin,
|
19
|
+
StatusBadgeConfig,
|
20
|
+
action,
|
23
21
|
display,
|
24
|
-
action
|
25
22
|
)
|
26
23
|
from django_cfg.modules.django_admin.utils.badges import StatusBadge
|
27
24
|
|
@@ -31,7 +28,7 @@ from ..services import MaintenanceService
|
|
31
28
|
|
32
29
|
class MaintenanceLogInline(TabularInline):
|
33
30
|
"""Inline for recent maintenance logs."""
|
34
|
-
|
31
|
+
|
35
32
|
model = MaintenanceLog
|
36
33
|
verbose_name = "Recent Log"
|
37
34
|
verbose_name_plural = "📋 Recent Maintenance Logs"
|
@@ -39,16 +36,16 @@ class MaintenanceLogInline(TabularInline):
|
|
39
36
|
max_num = 5
|
40
37
|
can_delete = False
|
41
38
|
show_change_link = True
|
42
|
-
|
39
|
+
|
43
40
|
fields = ['status_display', 'action', 'created_at', 'duration_seconds', 'error_preview']
|
44
41
|
readonly_fields = ['status_display', 'action', 'created_at', 'duration_seconds', 'error_preview']
|
45
|
-
|
42
|
+
|
46
43
|
def has_add_permission(self, request, obj=None):
|
47
44
|
return False
|
48
|
-
|
45
|
+
|
49
46
|
def has_change_permission(self, request, obj=None):
|
50
47
|
return False
|
51
|
-
|
48
|
+
|
52
49
|
@display(description="Status")
|
53
50
|
def status_display(self, obj):
|
54
51
|
"""Display status with badge."""
|
@@ -58,44 +55,44 @@ class MaintenanceLogInline(TabularInline):
|
|
58
55
|
MaintenanceLog.Status.PENDING: 'warning'
|
59
56
|
}
|
60
57
|
variant = status_variants.get(obj.status, 'secondary')
|
61
|
-
|
58
|
+
|
62
59
|
status_icons = {
|
63
60
|
MaintenanceLog.Status.SUCCESS: Icons.CHECK_CIRCLE,
|
64
61
|
MaintenanceLog.Status.FAILED: Icons.CANCEL,
|
65
62
|
MaintenanceLog.Status.PENDING: Icons.SCHEDULE
|
66
63
|
}
|
67
64
|
icon = status_icons.get(obj.status, Icons.HELP)
|
68
|
-
|
65
|
+
|
69
66
|
config = StatusBadgeConfig(show_icons=True, icon=icon)
|
70
67
|
return StatusBadge.create(
|
71
68
|
text=obj.get_status_display(),
|
72
69
|
variant=variant,
|
73
70
|
config=config
|
74
71
|
)
|
75
|
-
|
72
|
+
|
76
73
|
@display(description="Error")
|
77
74
|
def error_preview(self, obj):
|
78
75
|
"""Show error message preview."""
|
79
76
|
if not obj.error_message:
|
80
77
|
return "—"
|
81
|
-
|
78
|
+
|
82
79
|
preview = obj.error_message[:50]
|
83
80
|
if len(obj.error_message) > 50:
|
84
81
|
preview += "..."
|
85
|
-
|
82
|
+
|
86
83
|
return preview
|
87
84
|
|
88
85
|
|
89
86
|
@admin.register(CloudflareSite)
|
90
87
|
class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
91
88
|
"""Admin for CloudflareSite using Django Admin Utilities."""
|
92
|
-
|
89
|
+
|
93
90
|
# Performance optimization
|
94
91
|
select_related_fields = ['api_key']
|
95
|
-
|
92
|
+
|
96
93
|
list_display = [
|
97
94
|
'status_display',
|
98
|
-
'name_display',
|
95
|
+
'name_display',
|
99
96
|
'domain_display',
|
100
97
|
'subdomain_config_display',
|
101
98
|
'maintenance_display',
|
@@ -120,7 +117,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
120
117
|
'last_maintenance_at',
|
121
118
|
'logs_preview'
|
122
119
|
]
|
123
|
-
|
120
|
+
|
124
121
|
fieldsets = [
|
125
122
|
('🌐 Site Information', {
|
126
123
|
'fields': ['name', 'domain', 'zone_id'],
|
@@ -147,9 +144,9 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
147
144
|
'classes': ('tab', 'collapse')
|
148
145
|
})
|
149
146
|
]
|
150
|
-
|
147
|
+
|
151
148
|
inlines = [MaintenanceLogInline]
|
152
|
-
|
149
|
+
|
153
150
|
actions = [
|
154
151
|
'enable_maintenance_action',
|
155
152
|
'disable_maintenance_action',
|
@@ -157,7 +154,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
157
154
|
'deactivate_sites_action',
|
158
155
|
'sync_with_cloudflare_action'
|
159
156
|
]
|
160
|
-
|
157
|
+
|
161
158
|
@display(description="Status")
|
162
159
|
def status_display(self, obj: CloudflareSite) -> str:
|
163
160
|
"""Display site status with maintenance indicator."""
|
@@ -182,7 +179,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
182
179
|
variant="secondary",
|
183
180
|
config=config
|
184
181
|
)
|
185
|
-
|
182
|
+
|
186
183
|
@display(description="Name", ordering="name")
|
187
184
|
def name_display(self, obj: CloudflareSite) -> str:
|
188
185
|
"""Display site name."""
|
@@ -192,7 +189,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
192
189
|
variant="primary",
|
193
190
|
config=config
|
194
191
|
)
|
195
|
-
|
192
|
+
|
196
193
|
@display(description="Domain", ordering="domain")
|
197
194
|
def domain_display(self, obj: CloudflareSite) -> str:
|
198
195
|
"""Display domain."""
|
@@ -202,7 +199,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
202
199
|
variant="info",
|
203
200
|
config=config
|
204
201
|
)
|
205
|
-
|
202
|
+
|
206
203
|
@display(description="Subdomains")
|
207
204
|
def subdomain_config_display(self, obj: CloudflareSite) -> str:
|
208
205
|
"""Display subdomain configuration."""
|
@@ -211,7 +208,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
211
208
|
return StatusBadge.create(text="Includes Subdomains", variant="info", config=config)
|
212
209
|
else:
|
213
210
|
return "Domain Only"
|
214
|
-
|
211
|
+
|
215
212
|
@display(description="Maintenance")
|
216
213
|
def maintenance_display(self, obj: CloudflareSite) -> str:
|
217
214
|
"""Display maintenance status."""
|
@@ -221,7 +218,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
221
218
|
else:
|
222
219
|
config = StatusBadgeConfig(show_icons=True, icon=Icons.CHECK_CIRCLE)
|
223
220
|
return StatusBadge.create(text="Inactive", variant="success", config=config)
|
224
|
-
|
221
|
+
|
225
222
|
@display(description="Active")
|
226
223
|
def active_display(self, obj: CloudflareSite) -> str:
|
227
224
|
"""Display active status."""
|
@@ -231,7 +228,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
231
228
|
else:
|
232
229
|
config = StatusBadgeConfig(show_icons=True, icon=Icons.CANCEL)
|
233
230
|
return StatusBadge.create(text="Inactive", variant="secondary", config=config)
|
234
|
-
|
231
|
+
|
235
232
|
@display(description="Last Maintenance")
|
236
233
|
def last_maintenance_display(self, obj: CloudflareSite) -> str:
|
237
234
|
"""Display last maintenance time."""
|
@@ -239,7 +236,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
239
236
|
return "Never"
|
240
237
|
config = DateTimeDisplayConfig(show_relative=True)
|
241
238
|
return self.display_datetime_relative(obj, 'last_maintenance_at', config)
|
242
|
-
|
239
|
+
|
243
240
|
@display(description="Logs")
|
244
241
|
def logs_count(self, obj: CloudflareSite) -> str:
|
245
242
|
"""Display count of maintenance logs."""
|
@@ -247,35 +244,35 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
247
244
|
if count > 0:
|
248
245
|
return f"{count} logs"
|
249
246
|
return "No logs"
|
250
|
-
|
247
|
+
|
251
248
|
@display(description="API Key")
|
252
249
|
def api_key_display(self, obj: CloudflareSite) -> str:
|
253
250
|
"""Display API key."""
|
254
251
|
if not obj.api_key:
|
255
252
|
return "—"
|
256
253
|
return self.display_user_simple(obj.api_key, field_name='name')
|
257
|
-
|
254
|
+
|
258
255
|
def logs_preview(self, obj: CloudflareSite) -> str:
|
259
256
|
"""Show recent maintenance logs."""
|
260
257
|
logs = obj.maintenancelog_set.all()[:5]
|
261
|
-
|
258
|
+
|
262
259
|
if not logs:
|
263
260
|
return "No maintenance logs yet"
|
264
|
-
|
261
|
+
|
265
262
|
log_list = []
|
266
263
|
for log in logs:
|
267
264
|
status_emoji = "✅" if log.status == MaintenanceLog.Status.SUCCESS else "❌" if log.status == MaintenanceLog.Status.FAILED else "⏳"
|
268
265
|
log_list.append(f"{status_emoji} {log.action} - {log.created_at.strftime('%Y-%m-%d %H:%M')}")
|
269
|
-
|
266
|
+
|
270
267
|
return "\n".join(log_list)
|
271
|
-
|
268
|
+
|
272
269
|
@action(description="Enable maintenance mode", variant=ActionVariant.WARNING)
|
273
270
|
def enable_maintenance_action(self, request: HttpRequest, queryset) -> None:
|
274
271
|
"""Enable maintenance mode for selected sites."""
|
275
272
|
service = MaintenanceService()
|
276
273
|
success_count = 0
|
277
274
|
error_count = 0
|
278
|
-
|
275
|
+
|
279
276
|
for site in queryset:
|
280
277
|
try:
|
281
278
|
service.enable_maintenance(site)
|
@@ -283,19 +280,19 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
283
280
|
except Exception as e:
|
284
281
|
error_count += 1
|
285
282
|
messages.error(request, f"Failed to enable maintenance for {site.name}: {str(e)}")
|
286
|
-
|
283
|
+
|
287
284
|
if success_count > 0:
|
288
285
|
messages.success(request, f"Successfully enabled maintenance for {success_count} sites.")
|
289
286
|
if error_count > 0:
|
290
287
|
messages.error(request, f"Failed to enable maintenance for {error_count} sites.")
|
291
|
-
|
288
|
+
|
292
289
|
@action(description="Disable maintenance mode", variant=ActionVariant.SUCCESS)
|
293
290
|
def disable_maintenance_action(self, request: HttpRequest, queryset) -> None:
|
294
291
|
"""Disable maintenance mode for selected sites."""
|
295
292
|
service = MaintenanceService()
|
296
293
|
success_count = 0
|
297
294
|
error_count = 0
|
298
|
-
|
295
|
+
|
299
296
|
for site in queryset:
|
300
297
|
try:
|
301
298
|
service.disable_maintenance(site)
|
@@ -303,33 +300,33 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
303
300
|
except Exception as e:
|
304
301
|
error_count += 1
|
305
302
|
messages.error(request, f"Failed to disable maintenance for {site.name}: {str(e)}")
|
306
|
-
|
303
|
+
|
307
304
|
if success_count > 0:
|
308
305
|
messages.success(request, f"Successfully disabled maintenance for {success_count} sites.")
|
309
306
|
if error_count > 0:
|
310
307
|
messages.error(request, f"Failed to disable maintenance for {error_count} sites.")
|
311
|
-
|
308
|
+
|
312
309
|
@action(description="Activate sites", variant=ActionVariant.SUCCESS)
|
313
310
|
def activate_sites_action(self, request: HttpRequest, queryset) -> None:
|
314
311
|
"""Activate selected sites."""
|
315
312
|
count = queryset.update(is_active=True)
|
316
313
|
messages.success(request, f"Successfully activated {count} sites.")
|
317
|
-
|
314
|
+
|
318
315
|
@action(description="Deactivate sites", variant=ActionVariant.DANGER)
|
319
316
|
def deactivate_sites_action(self, request: HttpRequest, queryset) -> None:
|
320
317
|
"""Deactivate selected sites."""
|
321
318
|
count = queryset.update(is_active=False)
|
322
319
|
messages.warning(request, f"Successfully deactivated {count} sites.")
|
323
|
-
|
320
|
+
|
324
321
|
@action(description="Sync with Cloudflare", variant=ActionVariant.INFO)
|
325
322
|
def sync_with_cloudflare_action(self, request: HttpRequest, queryset) -> None:
|
326
323
|
"""Sync selected sites with Cloudflare."""
|
327
324
|
messages.info(request, f"Cloudflare sync initiated for {queryset.count()} sites.")
|
328
|
-
|
325
|
+
|
329
326
|
def changelist_view(self, request, extra_context=None):
|
330
327
|
"""Add site statistics to changelist."""
|
331
328
|
extra_context = extra_context or {}
|
332
|
-
|
329
|
+
|
333
330
|
queryset = self.get_queryset(request)
|
334
331
|
stats = queryset.aggregate(
|
335
332
|
total_sites=Count('id'),
|
@@ -337,12 +334,12 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
|
|
337
334
|
maintenance_sites=Count('id', filter=Q(maintenance_active=True)),
|
338
335
|
subdomain_sites=Count('id', filter=Q(include_subdomains=True))
|
339
336
|
)
|
340
|
-
|
337
|
+
|
341
338
|
extra_context['site_stats'] = {
|
342
339
|
'total_sites': stats['total_sites'] or 0,
|
343
340
|
'active_sites': stats['active_sites'] or 0,
|
344
341
|
'maintenance_sites': stats['maintenance_sites'] or 0,
|
345
342
|
'subdomain_sites': stats['subdomain_sites'] or 0
|
346
343
|
}
|
347
|
-
|
344
|
+
|
348
345
|
return super().changelist_view(request, extra_context)
|
@@ -7,11 +7,11 @@ from django.apps import AppConfig
|
|
7
7
|
|
8
8
|
class MaintenanceConfig(AppConfig):
|
9
9
|
"""Configuration for the simplified maintenance app."""
|
10
|
-
|
10
|
+
|
11
11
|
default_auto_field = 'django.db.models.BigAutoField'
|
12
12
|
name = 'django_cfg.apps.maintenance'
|
13
13
|
verbose_name = 'Maintenance Mode'
|
14
|
-
|
14
|
+
|
15
15
|
def ready(self):
|
16
16
|
"""Initialize app when Django starts."""
|
17
17
|
# No complex signals or initialization needed
|
@@ -5,9 +5,10 @@ Single command instead of 2+ complex commands.
|
|
5
5
|
Usage: python manage.py maintenance enable/disable/status/sync domain.com
|
6
6
|
"""
|
7
7
|
|
8
|
+
from typing import Any
|
9
|
+
|
8
10
|
from django.core.management.base import BaseCommand, CommandError
|
9
11
|
from django.db import transaction
|
10
|
-
from typing import Any, Optional
|
11
12
|
|
12
13
|
from ...models import CloudflareSite, MaintenanceLog
|
13
14
|
from ...services import MaintenanceService
|
@@ -15,9 +16,9 @@ from ...services import MaintenanceService
|
|
15
16
|
|
16
17
|
class Command(BaseCommand):
|
17
18
|
"""Simple maintenance management command."""
|
18
|
-
|
19
|
+
|
19
20
|
help = 'Manage maintenance mode for Cloudflare sites'
|
20
|
-
|
21
|
+
|
21
22
|
def add_arguments(self, parser) -> None:
|
22
23
|
"""Add command arguments."""
|
23
24
|
parser.add_argument(
|
@@ -25,31 +26,31 @@ class Command(BaseCommand):
|
|
25
26
|
choices=['enable', 'disable', 'status', 'sync', 'list'],
|
26
27
|
help='Action to perform'
|
27
28
|
)
|
28
|
-
|
29
|
+
|
29
30
|
parser.add_argument(
|
30
31
|
'domain',
|
31
32
|
nargs='?',
|
32
33
|
help='Domain to operate on (required for enable/disable/status/sync)'
|
33
34
|
)
|
34
|
-
|
35
|
+
|
35
36
|
parser.add_argument(
|
36
37
|
'--reason',
|
37
38
|
default='Maintenance via CLI',
|
38
39
|
help='Reason for enabling maintenance (default: "Maintenance via CLI")'
|
39
40
|
)
|
40
|
-
|
41
|
+
|
41
42
|
parser.add_argument(
|
42
43
|
'--force',
|
43
44
|
action='store_true',
|
44
45
|
help='Skip confirmation prompts'
|
45
46
|
)
|
46
|
-
|
47
|
+
|
47
48
|
parser.add_argument(
|
48
49
|
'--verbose',
|
49
50
|
action='store_true',
|
50
51
|
help='Show detailed output'
|
51
52
|
)
|
52
|
-
|
53
|
+
|
53
54
|
def handle(self, *args: Any, **options: Any) -> None:
|
54
55
|
"""Handle the command."""
|
55
56
|
action = options['action']
|
@@ -57,11 +58,11 @@ class Command(BaseCommand):
|
|
57
58
|
reason = options['reason']
|
58
59
|
force = options['force']
|
59
60
|
verbose = options['verbose']
|
60
|
-
|
61
|
+
|
61
62
|
# Validate arguments
|
62
63
|
if action in ['enable', 'disable', 'status', 'sync'] and not domain:
|
63
64
|
raise CommandError(f"Domain is required for '{action}' action")
|
64
|
-
|
65
|
+
|
65
66
|
try:
|
66
67
|
if action == 'list':
|
67
68
|
self._handle_list(verbose)
|
@@ -73,36 +74,36 @@ class Command(BaseCommand):
|
|
73
74
|
self._handle_disable(domain, force, verbose)
|
74
75
|
elif action == 'sync':
|
75
76
|
self._handle_sync(domain, verbose)
|
76
|
-
|
77
|
+
|
77
78
|
except CloudflareSite.DoesNotExist:
|
78
79
|
raise CommandError(f"Site '{domain}' not found. Use 'list' action to see available sites.")
|
79
80
|
except Exception as e:
|
80
81
|
raise CommandError(f"Operation failed: {str(e)}")
|
81
|
-
|
82
|
+
|
82
83
|
def _handle_list(self, verbose: bool) -> None:
|
83
84
|
"""List all sites."""
|
84
85
|
sites = CloudflareSite.objects.all().order_by('name')
|
85
|
-
|
86
|
+
|
86
87
|
if not sites:
|
87
88
|
self.stdout.write(self.style.WARNING("No sites configured"))
|
88
89
|
return
|
89
|
-
|
90
|
+
|
90
91
|
self.stdout.write(self.style.SUCCESS(f"Found {sites.count()} sites:"))
|
91
92
|
self.stdout.write("")
|
92
|
-
|
93
|
+
|
93
94
|
for site in sites:
|
94
95
|
status_style = self.style.WARNING if site.maintenance_active else self.style.SUCCESS
|
95
96
|
status_text = "🔧 MAINTENANCE" if site.maintenance_active else "🟢 ACTIVE"
|
96
|
-
|
97
|
+
|
97
98
|
self.stdout.write(f" {status_style(status_text)} {site.name} ({site.domain})")
|
98
|
-
|
99
|
+
|
99
100
|
if verbose:
|
100
101
|
self.stdout.write(f" Zone ID: {site.zone_id}")
|
101
102
|
self.stdout.write(f" Account ID: {site.account_id}")
|
102
103
|
self.stdout.write(f" Created: {site.created_at.strftime('%Y-%m-%d %H:%M')}")
|
103
104
|
if site.last_maintenance_at:
|
104
105
|
self.stdout.write(f" Last Maintenance: {site.last_maintenance_at.strftime('%Y-%m-%d %H:%M')}")
|
105
|
-
|
106
|
+
|
106
107
|
# Show recent logs
|
107
108
|
recent_logs = site.logs.all()[:3]
|
108
109
|
if recent_logs:
|
@@ -113,30 +114,30 @@ class Command(BaseCommand):
|
|
113
114
|
MaintenanceLog.Status.FAILED: "❌",
|
114
115
|
MaintenanceLog.Status.PENDING: "⏳"
|
115
116
|
}.get(log.status, "❓")
|
116
|
-
|
117
|
+
|
117
118
|
self.stdout.write(f" {status_emoji} {log.get_action_display()} - {log.created_at.strftime('%m-%d %H:%M')}")
|
118
|
-
|
119
|
+
|
119
120
|
self.stdout.write("")
|
120
|
-
|
121
|
+
|
121
122
|
def _handle_status(self, domain: str, verbose: bool) -> None:
|
122
123
|
"""Show status for specific site."""
|
123
124
|
site = CloudflareSite.objects.get(domain=domain)
|
124
|
-
|
125
|
+
|
125
126
|
status_style = self.style.WARNING if site.maintenance_active else self.style.SUCCESS
|
126
127
|
status_text = "🔧 MAINTENANCE ACTIVE" if site.maintenance_active else "🟢 ACTIVE"
|
127
|
-
|
128
|
+
|
128
129
|
self.stdout.write(f"Status for {site.name} ({domain}):")
|
129
130
|
self.stdout.write(f" {status_style(status_text)}")
|
130
|
-
|
131
|
+
|
131
132
|
if verbose:
|
132
133
|
self.stdout.write(f" Zone ID: {site.zone_id}")
|
133
134
|
self.stdout.write(f" Account ID: {site.account_id}")
|
134
135
|
self.stdout.write(f" Created: {site.created_at.strftime('%Y-%m-%d %H:%M')}")
|
135
136
|
self.stdout.write(f" Updated: {site.updated_at.strftime('%Y-%m-%d %H:%M')}")
|
136
|
-
|
137
|
+
|
137
138
|
if site.last_maintenance_at:
|
138
139
|
self.stdout.write(f" Last Maintenance: {site.last_maintenance_at.strftime('%Y-%m-%d %H:%M')}")
|
139
|
-
|
140
|
+
|
140
141
|
# Show recent logs
|
141
142
|
recent_logs = site.logs.all()[:5]
|
142
143
|
if recent_logs:
|
@@ -147,115 +148,115 @@ class Command(BaseCommand):
|
|
147
148
|
MaintenanceLog.Status.FAILED: "❌",
|
148
149
|
MaintenanceLog.Status.PENDING: "⏳"
|
149
150
|
}.get(log.status, "❓")
|
150
|
-
|
151
|
+
|
151
152
|
duration_text = f" ({log.duration_seconds}s)" if log.duration_seconds else ""
|
152
153
|
self.stdout.write(f" {status_emoji} {log.get_action_display()}{duration_text} - {log.created_at.strftime('%Y-%m-%d %H:%M')}")
|
153
|
-
|
154
|
+
|
154
155
|
if log.error_message and verbose:
|
155
156
|
self.stdout.write(f" Error: {log.error_message[:100]}")
|
156
|
-
|
157
|
+
|
157
158
|
def _handle_enable(self, domain: str, reason: str, force: bool, verbose: bool) -> None:
|
158
159
|
"""Enable maintenance for site."""
|
159
160
|
site = CloudflareSite.objects.get(domain=domain)
|
160
|
-
|
161
|
+
|
161
162
|
if site.maintenance_active:
|
162
163
|
self.stdout.write(self.style.WARNING(f"Maintenance is already active for {domain}"))
|
163
164
|
return
|
164
|
-
|
165
|
+
|
165
166
|
# Confirmation
|
166
167
|
if not force:
|
167
168
|
confirm = input(f"Enable maintenance for {site.name} ({domain})? [y/N]: ")
|
168
169
|
if confirm.lower() not in ['y', 'yes']:
|
169
170
|
self.stdout.write("Cancelled")
|
170
171
|
return
|
171
|
-
|
172
|
+
|
172
173
|
self.stdout.write(f"Enabling maintenance for {domain}...")
|
173
174
|
if verbose:
|
174
175
|
self.stdout.write(f"Reason: {reason}")
|
175
|
-
|
176
|
+
|
176
177
|
try:
|
177
178
|
with transaction.atomic():
|
178
179
|
service = MaintenanceService(site)
|
179
180
|
log_entry = service.enable_maintenance(reason)
|
180
|
-
|
181
|
+
|
181
182
|
if log_entry.status == MaintenanceLog.Status.SUCCESS:
|
182
183
|
duration_text = f" ({log_entry.duration_seconds}s)" if log_entry.duration_seconds else ""
|
183
184
|
self.stdout.write(self.style.SUCCESS(f"✅ Maintenance enabled successfully{duration_text}"))
|
184
|
-
|
185
|
+
|
185
186
|
if verbose and log_entry.cloudflare_response:
|
186
187
|
self.stdout.write("Cloudflare response:")
|
187
188
|
import json
|
188
189
|
self.stdout.write(json.dumps(log_entry.cloudflare_response, indent=2))
|
189
190
|
else:
|
190
191
|
self.stdout.write(self.style.ERROR(f"❌ Failed to enable maintenance: {log_entry.error_message}"))
|
191
|
-
|
192
|
+
|
192
193
|
except Exception as e:
|
193
194
|
self.stdout.write(self.style.ERROR(f"❌ Error: {str(e)}"))
|
194
|
-
|
195
|
+
|
195
196
|
def _handle_disable(self, domain: str, force: bool, verbose: bool) -> None:
|
196
197
|
"""Disable maintenance for site."""
|
197
198
|
site = CloudflareSite.objects.get(domain=domain)
|
198
|
-
|
199
|
+
|
199
200
|
if not site.maintenance_active:
|
200
201
|
self.stdout.write(self.style.WARNING(f"Maintenance is not active for {domain}"))
|
201
202
|
return
|
202
|
-
|
203
|
+
|
203
204
|
# Confirmation
|
204
205
|
if not force:
|
205
206
|
confirm = input(f"Disable maintenance for {site.name} ({domain})? [y/N]: ")
|
206
207
|
if confirm.lower() not in ['y', 'yes']:
|
207
208
|
self.stdout.write("Cancelled")
|
208
209
|
return
|
209
|
-
|
210
|
+
|
210
211
|
self.stdout.write(f"Disabling maintenance for {domain}...")
|
211
|
-
|
212
|
+
|
212
213
|
try:
|
213
214
|
with transaction.atomic():
|
214
215
|
service = MaintenanceService(site)
|
215
216
|
log_entry = service.disable_maintenance()
|
216
|
-
|
217
|
+
|
217
218
|
if log_entry.status == MaintenanceLog.Status.SUCCESS:
|
218
219
|
duration_text = f" ({log_entry.duration_seconds}s)" if log_entry.duration_seconds else ""
|
219
220
|
self.stdout.write(self.style.SUCCESS(f"✅ Maintenance disabled successfully{duration_text}"))
|
220
|
-
|
221
|
+
|
221
222
|
if verbose and log_entry.cloudflare_response:
|
222
223
|
self.stdout.write("Cloudflare response:")
|
223
224
|
import json
|
224
225
|
self.stdout.write(json.dumps(log_entry.cloudflare_response, indent=2))
|
225
226
|
else:
|
226
227
|
self.stdout.write(self.style.ERROR(f"❌ Failed to disable maintenance: {log_entry.error_message}"))
|
227
|
-
|
228
|
+
|
228
229
|
except Exception as e:
|
229
230
|
self.stdout.write(self.style.ERROR(f"❌ Error: {str(e)}"))
|
230
|
-
|
231
|
+
|
231
232
|
def _handle_sync(self, domain: str, verbose: bool) -> None:
|
232
233
|
"""Sync site from Cloudflare."""
|
233
234
|
site = CloudflareSite.objects.get(domain=domain)
|
234
|
-
|
235
|
+
|
235
236
|
self.stdout.write(f"Syncing {domain} from Cloudflare...")
|
236
|
-
|
237
|
+
|
237
238
|
try:
|
238
239
|
service = MaintenanceService(site)
|
239
240
|
log_entry = service.sync_site_from_cloudflare()
|
240
|
-
|
241
|
+
|
241
242
|
if log_entry.status == MaintenanceLog.Status.SUCCESS:
|
242
243
|
duration_text = f" ({log_entry.duration_seconds}s)" if log_entry.duration_seconds else ""
|
243
244
|
self.stdout.write(self.style.SUCCESS(f"✅ Sync completed successfully{duration_text}"))
|
244
|
-
|
245
|
+
|
245
246
|
if verbose and log_entry.cloudflare_response:
|
246
247
|
response = log_entry.cloudflare_response
|
247
248
|
if 'updated_fields' in response and response['updated_fields']:
|
248
249
|
self.stdout.write(f"Updated fields: {', '.join(response['updated_fields'])}")
|
249
|
-
|
250
|
+
|
250
251
|
maintenance_status = response.get('maintenance_active', 'unknown')
|
251
252
|
self.stdout.write(f"Current maintenance status: {maintenance_status}")
|
252
|
-
|
253
|
+
|
253
254
|
if verbose:
|
254
255
|
import json
|
255
256
|
self.stdout.write("Full Cloudflare response:")
|
256
257
|
self.stdout.write(json.dumps(response, indent=2))
|
257
258
|
else:
|
258
259
|
self.stdout.write(self.style.ERROR(f"❌ Sync failed: {log_entry.error_message}"))
|
259
|
-
|
260
|
+
|
260
261
|
except Exception as e:
|
261
262
|
self.stdout.write(self.style.ERROR(f"❌ Error: {str(e)}"))
|