django-cfg 1.4.21__py3-none-any.whl → 1.4.24__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 +36 -7
- 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.24.dist-info}/METADATA +1 -1
- django_cfg-1.4.24.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.24.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/licenses/LICENSE +0 -0
@@ -11,24 +11,24 @@ class UserActivity(models.Model):
|
|
11
11
|
"""
|
12
12
|
User activity log.
|
13
13
|
"""
|
14
|
-
|
14
|
+
|
15
15
|
user = models.ForeignKey('CustomUser', on_delete=models.CASCADE, related_name='activities')
|
16
16
|
activity_type = models.CharField(max_length=20, choices=ActivityType.choices)
|
17
17
|
description = models.TextField(blank=True)
|
18
18
|
ip_address = models.GenericIPAddressField(null=True, blank=True)
|
19
19
|
user_agent = models.TextField(blank=True)
|
20
|
-
|
20
|
+
|
21
21
|
# Related objects (generic foreign key could be used here)
|
22
22
|
object_id = models.PositiveIntegerField(null=True, blank=True)
|
23
23
|
object_type = models.CharField(max_length=50, blank=True)
|
24
|
-
|
24
|
+
|
25
25
|
created_at = models.DateTimeField(auto_now_add=True)
|
26
|
-
|
26
|
+
|
27
27
|
class Meta:
|
28
28
|
app_label = 'django_cfg_accounts'
|
29
29
|
verbose_name = 'User Activity'
|
30
30
|
verbose_name_plural = 'User Activities'
|
31
31
|
ordering = ['-created_at']
|
32
|
-
|
32
|
+
|
33
33
|
def __str__(self):
|
34
34
|
return f"{self.user.username} - {self.get_activity_type_display()}"
|
@@ -9,46 +9,46 @@ from .choices import TwilioResponseType, TwilioServiceType
|
|
9
9
|
|
10
10
|
class TwilioResponse(models.Model):
|
11
11
|
"""Model for storing Twilio API responses and webhook data."""
|
12
|
-
|
12
|
+
|
13
13
|
response_type = models.CharField(max_length=20, choices=TwilioResponseType.choices)
|
14
14
|
service_type = models.CharField(max_length=10, choices=TwilioServiceType.choices)
|
15
|
-
|
15
|
+
|
16
16
|
# Twilio identifiers
|
17
17
|
message_sid = models.CharField(max_length=34, blank=True, help_text="Twilio Message SID")
|
18
18
|
verification_sid = models.CharField(max_length=34, blank=True, help_text="Twilio Verification SID")
|
19
|
-
|
19
|
+
|
20
20
|
# Request/Response data
|
21
21
|
request_data = models.JSONField(default=dict, help_text="Original request parameters")
|
22
22
|
response_data = models.JSONField(default=dict, help_text="Twilio API response")
|
23
|
-
|
23
|
+
|
24
24
|
# Status and error handling
|
25
25
|
status = models.CharField(max_length=20, blank=True, help_text="Message/Verification status")
|
26
26
|
error_code = models.CharField(max_length=10, blank=True, help_text="Twilio error code")
|
27
27
|
error_message = models.TextField(blank=True, help_text="Error description")
|
28
|
-
|
28
|
+
|
29
29
|
# Contact information
|
30
30
|
to_number = models.CharField(max_length=20, blank=True, help_text="Recipient phone/email")
|
31
31
|
from_number = models.CharField(max_length=20, blank=True, help_text="Sender phone/email")
|
32
|
-
|
32
|
+
|
33
33
|
# Pricing
|
34
34
|
price = models.DecimalField(max_digits=10, decimal_places=6, null=True, blank=True)
|
35
35
|
price_unit = models.CharField(max_length=3, blank=True, help_text="Currency code")
|
36
|
-
|
36
|
+
|
37
37
|
# Timestamps
|
38
38
|
created_at = models.DateTimeField(auto_now_add=True)
|
39
39
|
updated_at = models.DateTimeField(auto_now=True)
|
40
40
|
twilio_created_at = models.DateTimeField(null=True, blank=True, help_text="Timestamp from Twilio")
|
41
|
-
|
41
|
+
|
42
42
|
# Relations
|
43
43
|
otp_secret = models.ForeignKey(
|
44
|
-
'OTPSecret',
|
45
|
-
on_delete=models.SET_NULL,
|
46
|
-
null=True,
|
44
|
+
'OTPSecret',
|
45
|
+
on_delete=models.SET_NULL,
|
46
|
+
null=True,
|
47
47
|
blank=True,
|
48
48
|
related_name='twilio_responses',
|
49
49
|
help_text="Related OTP if applicable"
|
50
50
|
)
|
51
|
-
|
51
|
+
|
52
52
|
class Meta:
|
53
53
|
app_label = 'django_cfg_accounts'
|
54
54
|
verbose_name = 'Twilio Response'
|
@@ -60,15 +60,15 @@ class TwilioResponse(models.Model):
|
|
60
60
|
models.Index(fields=['status', 'created_at']),
|
61
61
|
models.Index(fields=['response_type', 'service_type']),
|
62
62
|
]
|
63
|
-
|
63
|
+
|
64
64
|
def __str__(self):
|
65
65
|
return f"{self.get_response_type_display()} - {self.get_service_type_display()}"
|
66
|
-
|
66
|
+
|
67
67
|
@property
|
68
68
|
def has_error(self):
|
69
69
|
"""Check if response has error."""
|
70
70
|
return bool(self.error_code or self.error_message)
|
71
|
-
|
71
|
+
|
72
72
|
@property
|
73
73
|
def is_successful(self):
|
74
74
|
"""Check if response is successful."""
|
@@ -2,9 +2,10 @@
|
|
2
2
|
Registration and source tracking models.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from django.db import models
|
6
5
|
from urllib.parse import urlparse
|
7
6
|
|
7
|
+
from django.db import models
|
8
|
+
|
8
9
|
|
9
10
|
class RegistrationSource(models.Model):
|
10
11
|
"""Model for tracking user registration sources/projects."""
|
@@ -43,7 +44,7 @@ class UserRegistrationSource(models.Model):
|
|
43
44
|
source = models.ForeignKey(RegistrationSource, on_delete=models.CASCADE, related_name='user_registration_sources')
|
44
45
|
first_registration = models.BooleanField(default=True, help_text="Whether this was the first registration from this source")
|
45
46
|
registration_date = models.DateTimeField(auto_now_add=True)
|
46
|
-
|
47
|
+
|
47
48
|
class Meta:
|
48
49
|
app_label = 'django_cfg_accounts'
|
49
50
|
unique_together = ['user', 'source']
|
@@ -2,7 +2,8 @@
|
|
2
2
|
User model and related functionality.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from typing import
|
5
|
+
from typing import List, Optional
|
6
|
+
|
6
7
|
from django.contrib.auth.models import AbstractUser
|
7
8
|
from django.db import models
|
8
9
|
|
@@ -69,7 +70,7 @@ class CustomUser(AbstractUser):
|
|
69
70
|
"""Get the first source where user registered."""
|
70
71
|
from .registration import UserRegistrationSource
|
71
72
|
user_source = UserRegistrationSource.objects.filter(
|
72
|
-
user=self,
|
73
|
+
user=self,
|
73
74
|
first_registration=True
|
74
75
|
).first()
|
75
76
|
return user_source.source if user_source else None
|
@@ -1,9 +1,16 @@
|
|
1
|
-
from .
|
2
|
-
|
1
|
+
from .otp import (
|
2
|
+
OTPErrorResponseSerializer,
|
3
|
+
OTPRequestResponseSerializer,
|
4
|
+
OTPRequestSerializer,
|
5
|
+
OTPSerializer,
|
6
|
+
OTPVerifyResponseSerializer,
|
7
|
+
OTPVerifySerializer,
|
8
|
+
)
|
9
|
+
from .profile import UserProfileUpdateSerializer, UserSerializer
|
3
10
|
|
4
11
|
__all__ = [
|
5
12
|
'UserSerializer',
|
6
|
-
'UserProfileUpdateSerializer',
|
13
|
+
'UserProfileUpdateSerializer',
|
7
14
|
'OTPSerializer',
|
8
15
|
'OTPRequestSerializer',
|
9
16
|
'OTPVerifySerializer',
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from rest_framework import serializers
|
2
|
+
|
2
3
|
from ..models import OTPSecret
|
3
4
|
from .profile import UserSerializer
|
4
5
|
|
@@ -33,11 +34,11 @@ class OTPRequestSerializer(serializers.Serializer):
|
|
33
34
|
"""Validate identifier format."""
|
34
35
|
if not value:
|
35
36
|
raise serializers.ValidationError("Identifier is required.")
|
36
|
-
|
37
|
+
|
37
38
|
value = value.strip()
|
38
39
|
if not value:
|
39
40
|
raise serializers.ValidationError("Identifier cannot be empty.")
|
40
|
-
|
41
|
+
|
41
42
|
# Auto-detect if it's email or phone
|
42
43
|
if '@' in value:
|
43
44
|
# Basic email validation
|
@@ -81,11 +82,11 @@ class OTPVerifySerializer(serializers.Serializer):
|
|
81
82
|
"""Validate identifier format."""
|
82
83
|
if not value:
|
83
84
|
raise serializers.ValidationError("Identifier is required.")
|
84
|
-
|
85
|
+
|
85
86
|
value = value.strip()
|
86
87
|
if not value:
|
87
88
|
raise serializers.ValidationError("Identifier cannot be empty.")
|
88
|
-
|
89
|
+
|
89
90
|
# Auto-detect if it's email or phone
|
90
91
|
if '@' in value:
|
91
92
|
# Basic email validation
|
@@ -3,7 +3,6 @@ from rest_framework import serializers
|
|
3
3
|
from ..models import CustomUser, RegistrationSource, UserRegistrationSource
|
4
4
|
|
5
5
|
|
6
|
-
|
7
6
|
class UserSerializer(serializers.ModelSerializer):
|
8
7
|
"""Serializer for user details."""
|
9
8
|
|
@@ -130,7 +129,7 @@ class RegistrationSourceSerializer(serializers.ModelSerializer):
|
|
130
129
|
class UserRegistrationSourceSerializer(serializers.ModelSerializer):
|
131
130
|
"""Serializer for UserRegistrationSource model."""
|
132
131
|
source = RegistrationSourceSerializer(read_only=True)
|
133
|
-
|
132
|
+
|
134
133
|
class Meta:
|
135
134
|
model = UserRegistrationSource
|
136
135
|
fields = ["id", "user", "source", "first_registration", "registration_date"]
|
@@ -141,15 +140,15 @@ class UserWithSourcesSerializer(UserSerializer):
|
|
141
140
|
"""Extended user serializer with sources information."""
|
142
141
|
sources = serializers.SerializerMethodField()
|
143
142
|
primary_source = serializers.SerializerMethodField()
|
144
|
-
|
143
|
+
|
145
144
|
class Meta(UserSerializer.Meta):
|
146
145
|
fields = UserSerializer.Meta.fields + ['sources', 'primary_source']
|
147
|
-
|
146
|
+
|
148
147
|
def get_sources(self, obj):
|
149
148
|
"""Get all sources for the user."""
|
150
149
|
user_sources = UserRegistrationSource.objects.filter(user=obj).select_related('source')
|
151
150
|
return UserRegistrationSourceSerializer(user_sources, many=True).data
|
152
|
-
|
151
|
+
|
153
152
|
def get_primary_source(self, obj):
|
154
153
|
"""Get the primary source for the user."""
|
155
154
|
primary_source = obj.primary_source
|
@@ -15,59 +15,59 @@ class TwilioWebhookSerializer(serializers.Serializer):
|
|
15
15
|
from Twilio. The fields are optional because different webhook types
|
16
16
|
send different data.
|
17
17
|
"""
|
18
|
-
|
18
|
+
|
19
19
|
# Message-related fields (SMS/WhatsApp)
|
20
20
|
MessageSid = serializers.CharField(required=False, help_text="Twilio Message SID")
|
21
21
|
MessageStatus = serializers.CharField(required=False, help_text="Message status (sent, delivered, failed, etc.)")
|
22
22
|
To = serializers.CharField(required=False, help_text="Recipient phone number")
|
23
23
|
From = serializers.CharField(required=False, help_text="Sender phone number")
|
24
24
|
Body = serializers.CharField(required=False, help_text="Message body")
|
25
|
-
|
25
|
+
|
26
26
|
# Error fields
|
27
27
|
ErrorCode = serializers.CharField(required=False, help_text="Twilio error code")
|
28
28
|
ErrorMessage = serializers.CharField(required=False, help_text="Error message description")
|
29
|
-
|
29
|
+
|
30
30
|
# Pricing fields
|
31
31
|
Price = serializers.DecimalField(max_digits=10, decimal_places=6, required=False, help_text="Message price")
|
32
32
|
PriceUnit = serializers.CharField(required=False, help_text="Currency code")
|
33
|
-
|
33
|
+
|
34
34
|
# Verification-related fields (Verify API)
|
35
35
|
VerificationSid = serializers.CharField(required=False, help_text="Twilio Verification SID")
|
36
36
|
VerificationStatus = serializers.CharField(required=False, help_text="Verification status (approved, canceled, etc.)")
|
37
37
|
Channel = serializers.CharField(required=False, help_text="Verification channel (sms, whatsapp, call)")
|
38
|
-
|
38
|
+
|
39
39
|
# Timestamp fields
|
40
40
|
DateCreated = serializers.DateTimeField(required=False, help_text="When the message was created")
|
41
41
|
DateSent = serializers.DateTimeField(required=False, help_text="When the message was sent")
|
42
42
|
DateUpdated = serializers.DateTimeField(required=False, help_text="When the status was last updated")
|
43
|
-
|
43
|
+
|
44
44
|
# Account information
|
45
45
|
AccountSid = serializers.CharField(required=False, help_text="Twilio Account SID")
|
46
|
-
|
46
|
+
|
47
47
|
# Additional fields that might be present
|
48
48
|
Direction = serializers.CharField(required=False, help_text="Message direction (inbound/outbound)")
|
49
49
|
ApiVersion = serializers.CharField(required=False, help_text="Twilio API version")
|
50
|
-
|
50
|
+
|
51
51
|
# Alternative field names (some webhooks use different casing)
|
52
52
|
message_sid = serializers.CharField(required=False, help_text="Alternative field name for MessageSid")
|
53
53
|
message_status = serializers.CharField(required=False, help_text="Alternative field name for MessageStatus")
|
54
54
|
verification_sid = serializers.CharField(required=False, help_text="Alternative field name for VerificationSid")
|
55
55
|
verification_status = serializers.CharField(required=False, help_text="Alternative field name for VerificationStatus")
|
56
|
-
|
56
|
+
|
57
57
|
def validate(self, data):
|
58
58
|
"""
|
59
59
|
Ensure that we have at least one of the required identifiers.
|
60
60
|
"""
|
61
61
|
message_sid = data.get('MessageSid') or data.get('message_sid')
|
62
62
|
verification_sid = data.get('VerificationSid') or data.get('verification_sid')
|
63
|
-
|
63
|
+
|
64
64
|
if not message_sid and not verification_sid:
|
65
65
|
raise serializers.ValidationError(
|
66
66
|
"Either MessageSid or VerificationSid must be provided"
|
67
67
|
)
|
68
|
-
|
68
|
+
|
69
69
|
return data
|
70
|
-
|
70
|
+
|
71
71
|
def to_internal_value(self, data):
|
72
72
|
"""
|
73
73
|
Convert the webhook data to internal format.
|
@@ -78,7 +78,7 @@ class TwilioWebhookSerializer(serializers.Serializer):
|
|
78
78
|
if hasattr(data, 'items'):
|
79
79
|
# Convert QueryDict or dict to regular dict
|
80
80
|
data = dict(data.items()) if hasattr(data, 'items') else data
|
81
|
-
|
81
|
+
|
82
82
|
return super().to_internal_value(data)
|
83
83
|
|
84
84
|
|
@@ -3,7 +3,8 @@ User activity logging service.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
-
from typing import
|
6
|
+
from typing import Any, Dict, Optional
|
7
|
+
|
7
8
|
from django.utils import timezone
|
8
9
|
|
9
10
|
from ..models import CustomUser, UserActivity
|
@@ -49,10 +50,10 @@ class ActivityService:
|
|
49
50
|
object_id=object_id,
|
50
51
|
object_type=object_type,
|
51
52
|
)
|
52
|
-
|
53
|
+
|
53
54
|
logger.debug(f"Logged activity '{activity_type}' for user {user.email}")
|
54
55
|
return activity
|
55
|
-
|
56
|
+
|
56
57
|
except Exception as e:
|
57
58
|
logger.error(f"Failed to log activity '{activity_type}' for user {user.email}: {e}")
|
58
59
|
return None
|
@@ -75,10 +76,10 @@ class ActivityService:
|
|
75
76
|
List of UserActivity instances
|
76
77
|
"""
|
77
78
|
queryset = user.activities.all()
|
78
|
-
|
79
|
+
|
79
80
|
if activity_type:
|
80
81
|
queryset = queryset.filter(activity_type=activity_type)
|
81
|
-
|
82
|
+
|
82
83
|
return list(queryset.order_by('-created_at')[:limit])
|
83
84
|
|
84
85
|
@staticmethod
|
@@ -93,9 +94,9 @@ class ActivityService:
|
|
93
94
|
Dictionary with activity statistics
|
94
95
|
"""
|
95
96
|
now = timezone.now()
|
96
|
-
|
97
|
+
|
97
98
|
activities = user.activities.all()
|
98
|
-
|
99
|
+
|
99
100
|
stats = {
|
100
101
|
"total_activities": activities.count(),
|
101
102
|
"recent_24h": activities.filter(
|
@@ -108,15 +109,15 @@ class ActivityService:
|
|
108
109
|
created_at__gte=now - timezone.timedelta(days=30)
|
109
110
|
).count(),
|
110
111
|
}
|
111
|
-
|
112
|
+
|
112
113
|
# Activity type breakdown
|
113
114
|
activity_types = activities.values_list('activity_type', flat=True)
|
114
115
|
type_counts = {}
|
115
116
|
for activity_type in activity_types:
|
116
117
|
type_counts[activity_type] = type_counts.get(activity_type, 0) + 1
|
117
|
-
|
118
|
+
|
118
119
|
stats["by_type"] = type_counts
|
119
|
-
|
120
|
+
|
120
121
|
return stats
|
121
122
|
|
122
123
|
@staticmethod
|
@@ -131,10 +132,10 @@ class ActivityService:
|
|
131
132
|
Number of activities deleted
|
132
133
|
"""
|
133
134
|
cutoff_date = timezone.now() - timezone.timedelta(days=days)
|
134
|
-
|
135
|
+
|
135
136
|
deleted_count, _ = UserActivity.objects.filter(
|
136
137
|
created_at__lt=cutoff_date
|
137
138
|
).delete()
|
138
|
-
|
139
|
+
|
139
140
|
logger.info(f"Cleaned up {deleted_count} old activities older than {days} days")
|
140
141
|
return deleted_count
|
@@ -1,13 +1,15 @@
|
|
1
1
|
import logging
|
2
2
|
import traceback
|
3
|
-
from django.utils import timezone
|
4
|
-
from django.db import transaction
|
5
3
|
from typing import Optional
|
6
4
|
|
5
|
+
from django.db import transaction
|
6
|
+
from django.utils import timezone
|
7
|
+
|
7
8
|
from django_cfg.modules.django_telegram import DjangoTelegram
|
8
|
-
|
9
|
-
from ..
|
9
|
+
|
10
|
+
from ..models import CustomUser, OTPSecret
|
10
11
|
from ..signals import notify_failed_otp_attempt
|
12
|
+
from ..utils.notifications import AccountNotifications
|
11
13
|
|
12
14
|
logger = logging.getLogger(__name__)
|
13
15
|
|
@@ -97,8 +99,8 @@ class OTPService:
|
|
97
99
|
|
98
100
|
# Send Telegram notification for OTP request
|
99
101
|
try:
|
100
|
-
|
101
|
-
|
102
|
+
|
103
|
+
|
102
104
|
# Prepare notification data
|
103
105
|
notification_data = {
|
104
106
|
"Email": cleaned_email,
|
@@ -107,14 +109,14 @@ class OTPService:
|
|
107
109
|
"Source URL": source_url or "Direct",
|
108
110
|
"Timestamp": timezone.now().strftime("%Y-%m-%d %H:%M:%S UTC")
|
109
111
|
}
|
110
|
-
|
112
|
+
|
111
113
|
if created:
|
112
114
|
DjangoTelegram.send_success("New User OTP Request", notification_data)
|
113
115
|
else:
|
114
116
|
DjangoTelegram.send_info("OTP Login Request", notification_data)
|
115
|
-
|
117
|
+
|
116
118
|
logger.info(f"Telegram OTP notification sent for {cleaned_email}")
|
117
|
-
|
119
|
+
|
118
120
|
except ImportError:
|
119
121
|
logger.warning("django_cfg DjangoTelegram not available for OTP notifications")
|
120
122
|
except Exception as telegram_error:
|
@@ -150,13 +152,13 @@ class OTPService:
|
|
150
152
|
|
151
153
|
if not otp_secret or not otp_secret.is_valid:
|
152
154
|
logger.warning(f"Invalid OTP for {cleaned_email}")
|
153
|
-
|
155
|
+
|
154
156
|
# Send Telegram notification for failed OTP attempt
|
155
157
|
try:
|
156
158
|
notify_failed_otp_attempt(cleaned_email, reason="Invalid or expired OTP")
|
157
159
|
except Exception as e:
|
158
160
|
logger.error(f"Failed to send failed OTP notification: {e}")
|
159
|
-
|
161
|
+
|
160
162
|
return None
|
161
163
|
|
162
164
|
# Mark OTP as used
|
@@ -174,7 +176,7 @@ class OTPService:
|
|
174
176
|
|
175
177
|
# Send Telegram notification for successful OTP verification
|
176
178
|
try:
|
177
|
-
|
179
|
+
|
178
180
|
verification_data = {
|
179
181
|
"Email": cleaned_email,
|
180
182
|
"Username": user.username,
|
@@ -182,10 +184,10 @@ class OTPService:
|
|
182
184
|
"Login Time": timezone.now().strftime("%Y-%m-%d %H:%M:%S UTC"),
|
183
185
|
"User ID": user.id
|
184
186
|
}
|
185
|
-
|
187
|
+
|
186
188
|
DjangoTelegram.send_success("Successful OTP Login", verification_data)
|
187
189
|
logger.info(f"Telegram OTP verification notification sent for {cleaned_email}")
|
188
|
-
|
190
|
+
|
189
191
|
except ImportError:
|
190
192
|
logger.warning("django_cfg DjangoTelegram not available for OTP verification notifications")
|
191
193
|
except Exception as telegram_error:
|
@@ -3,14 +3,16 @@ Django signals for automatic email notifications on user account changes.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
+
|
7
|
+
from django.contrib.auth import get_user_model
|
6
8
|
from django.db.models.signals import post_save, pre_save
|
7
9
|
from django.dispatch import receiver
|
8
|
-
from django.contrib.auth import get_user_model
|
9
10
|
from django.utils import timezone
|
10
11
|
|
11
|
-
from .utils.notifications import AccountNotifications
|
12
12
|
from django_cfg.modules.django_telegram import DjangoTelegram
|
13
13
|
|
14
|
+
from .utils.notifications import AccountNotifications
|
15
|
+
|
14
16
|
User = get_user_model()
|
15
17
|
logger = logging.getLogger(__name__)
|
16
18
|
|
@@ -30,7 +32,7 @@ def send_user_status_change_emails(sender, instance, **kwargs):
|
|
30
32
|
# Get the old instance from database
|
31
33
|
if instance.pk:
|
32
34
|
old_instance = User.objects.get(pk=instance.pk)
|
33
|
-
|
35
|
+
|
34
36
|
# Check if user was activated
|
35
37
|
if not old_instance.is_active and instance.is_active:
|
36
38
|
AccountNotifications.send_account_status_change(instance, "activated")
|
@@ -40,7 +42,7 @@ def send_user_status_change_emails(sender, instance, **kwargs):
|
|
40
42
|
elif old_instance.is_active and not instance.is_active:
|
41
43
|
AccountNotifications.send_account_status_change(instance, "deactivated", reason="Account deactivated by administrator")
|
42
44
|
logger.info(f"Account deactivation email sent to {instance.email}")
|
43
|
-
|
45
|
+
|
44
46
|
except User.DoesNotExist:
|
45
47
|
# New user, no old instance to compare
|
46
48
|
pass
|
@@ -55,24 +57,24 @@ def send_user_profile_update_email(sender, instance, **kwargs):
|
|
55
57
|
# Get the old instance from database
|
56
58
|
if instance.pk:
|
57
59
|
old_instance = User.objects.get(pk=instance.pk)
|
58
|
-
|
60
|
+
|
59
61
|
# Check for important changes
|
60
62
|
changes = []
|
61
|
-
|
63
|
+
|
62
64
|
if old_instance.email != instance.email:
|
63
65
|
changes.append("email address")
|
64
|
-
|
66
|
+
|
65
67
|
if old_instance.username != instance.username:
|
66
68
|
changes.append("username")
|
67
|
-
|
69
|
+
|
68
70
|
if old_instance.first_name != instance.first_name or old_instance.last_name != instance.last_name:
|
69
71
|
changes.append("name")
|
70
|
-
|
72
|
+
|
71
73
|
# Send notification if there were important changes
|
72
74
|
if changes:
|
73
75
|
AccountNotifications.send_profile_update_notification(instance, changes, send_email=True, send_telegram=True)
|
74
76
|
logger.info(f"Profile update notification sent to {instance.email}")
|
75
|
-
|
77
|
+
|
76
78
|
except User.DoesNotExist:
|
77
79
|
pass
|
78
80
|
except Exception as e:
|
@@ -112,17 +114,17 @@ def trigger_login_notification(user, ip_address=None):
|
|
112
114
|
def send_security_telegram_alert(title: str, user_email: str, details: dict):
|
113
115
|
"""Send security alert via Telegram."""
|
114
116
|
try:
|
115
|
-
|
117
|
+
|
116
118
|
alert_data = {
|
117
119
|
"User": user_email,
|
118
120
|
"Alert Type": title,
|
119
121
|
"Timestamp": timezone.now().strftime("%Y-%m-%d %H:%M:%S UTC"),
|
120
122
|
**details
|
121
123
|
}
|
122
|
-
|
124
|
+
|
123
125
|
DjangoTelegram.send_warning(f"Security Alert: {title}", alert_data)
|
124
126
|
logger.info(f"Security Telegram alert sent: {title} for {user_email}")
|
125
|
-
|
127
|
+
|
126
128
|
except ImportError:
|
127
129
|
logger.warning("django_cfg DjangoTelegram not available for security alerts")
|
128
130
|
except Exception as e:
|
@@ -138,8 +140,8 @@ def notify_failed_otp_attempt(email: str, ip_address: str = None, reason: str =
|
|
138
140
|
"IP Address": ip_address or "Unknown",
|
139
141
|
"Attempt Time": timezone.now().strftime("%Y-%m-%d %H:%M:%S UTC")
|
140
142
|
}
|
141
|
-
|
143
|
+
|
142
144
|
send_security_telegram_alert("Failed OTP Attempt", email, details)
|
143
|
-
|
145
|
+
|
144
146
|
except Exception as e:
|
145
|
-
logger.error(f"Failed to send failed OTP notification: {e}")
|
147
|
+
logger.error(f"Failed to send failed OTP notification: {e}")
|
django_cfg/apps/accounts/urls.py
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
from django.urls import
|
1
|
+
from django.urls import include, path
|
2
|
+
from drf_spectacular.utils import extend_schema
|
2
3
|
from rest_framework.routers import DefaultRouter
|
3
4
|
from rest_framework_simplejwt.views import TokenRefreshView
|
4
|
-
from drf_spectacular.utils import extend_schema
|
5
5
|
|
6
6
|
from .views import OTPViewSet
|
7
|
-
from .views.profile import
|
7
|
+
from .views.profile import (
|
8
|
+
UserProfilePartialUpdateView,
|
9
|
+
UserProfileUpdateView,
|
10
|
+
UserProfileView,
|
11
|
+
upload_avatar,
|
12
|
+
)
|
8
13
|
|
9
14
|
app_name = 'cfg_accounts'
|
10
15
|
|
@@ -35,10 +40,10 @@ profile_patterns = [
|
|
35
40
|
urlpatterns = [
|
36
41
|
# ViewSet-based endpoints
|
37
42
|
path('', include(router.urls)),
|
38
|
-
|
43
|
+
|
39
44
|
# Token endpoints
|
40
45
|
path('token/', include(token_patterns)),
|
41
|
-
|
46
|
+
|
42
47
|
# Profile endpoints
|
43
48
|
path('profile/', include(profile_patterns)),
|
44
49
|
]
|