django-cfg 1.1.51__tar.gz → 1.1.52__tar.gz
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-1.1.51 → django_cfg-1.1.52}/PKG-INFO +1 -1
- {django_cfg-1.1.51 → django_cfg-1.1.52}/pyproject.toml +1 -1
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/__init__.py +1 -1
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/otp_service.py +28 -24
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/__init__.py +5 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/twilio_service.py +80 -3
- {django_cfg-1.1.51 → django_cfg-1.1.52}/.gitignore +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/LICENSE +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/MANIFEST.in +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/requirements-dev.txt +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/requirements-test.txt +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/requirements.txt +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/activity.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/filters.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/group.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/inlines.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/otp.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/registration_source.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/twilio_response.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/user.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/apps.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/management/commands/test_otp.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/managers/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/managers/user_manager.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/0002_add_phone_otp_clean.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/0003_twilioresponse.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/models.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/otp.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/profile.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/webhook.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/activity_service.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/signals.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/base_email.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/base_email.txt +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/otp_email.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/otp_email.txt +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/welcome_email.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/welcome_email.txt +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/utils/notifications.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/otp.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/profile.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/webhook.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/commands/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/commands/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/commands/views.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/health/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/health/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/health/views.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/admin.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/apps.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/migrations/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/models.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/serializers.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/signals.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/tests.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/views.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/admin.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/admin_filters.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/apps.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/management/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/management/commands/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/management/commands/test_newsletter.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/managers/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/managers/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/migrations/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/models.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/serializers.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/services/email_service.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/signals.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/utils/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/campaigns.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/emails.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/newsletters.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/subscriptions.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/tracking.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/admin.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/admin_filters.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/apps.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/managers/message_manager.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/managers/ticket_manager.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/migrations/0002_alter_message_ticket.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/migrations/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/models.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/serializers.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/signals.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/templates/support/chat/access_denied.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/templates/support/chat/ticket_chat.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/utils/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/utils/support_email_service.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/admin.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/api.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/chat.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/admin.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/apps.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/views.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/archive/django_sample.zip +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/commands/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/commands/create_project.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/commands/info.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/main.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/utils.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/config.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/environment.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/generation.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/validation.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/exceptions.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/integration.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/check_settings.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/create_token.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/generate.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/list_urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/migrator.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/rundramatiq.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/runserver_ngrok.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/script.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/show_config.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/show_urls.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/superuser.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/task_clear.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/task_status.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/test_email.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/test_telegram.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/test_twilio.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/tree.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/validate_config.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/middleware/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/middleware/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/middleware/user_activity.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/cache.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/constance.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/database.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/drf.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/jwt.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/limits.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/ngrok.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/revolution.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/services.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/tasks.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/unfold.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/base.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/cache.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/converter.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/service.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_email.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/example.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/cache.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/client.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/models_cache.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/service.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/translator/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/translator/cache.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/translator/translator.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_logger.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_ngrok.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_tasks.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_telegram.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/README.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/exceptions.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/models.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/sendgrid_service.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/templates/guide.md +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/templates/sendgrid_otp_email.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/templates/sendgrid_test_data.json +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/logger.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/callbacks.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/dashboard.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/models.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/system_monitor.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/tailwind.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/routers.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/index.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/layouts/dashboard_with_tabs.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/activity_tracker.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/charts_section.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/django_commands.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/quick_actions.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/recent_activity.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/recent_users_table.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/stats_cards.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/stats_tiles.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/system_health.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/system_metrics.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/user_permissions.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/app_stats_tab.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/commands_tab.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/overview_tab.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/stats_tab.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/users_tab.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/zones/zones_table.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/emails/base_email.html +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/utils/__init__.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/utils/path_resolution.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/utils/smart_defaults.py +0 -0
- {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/version_check.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: django-cfg
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.52
|
4
4
|
Summary: 🚀 Production-ready Django configuration framework with type-safe settings, smart automation, and modern developer experience
|
5
5
|
Project-URL: Homepage, https://github.com/markolofsen/django-cfg
|
6
6
|
Project-URL: Documentation, https://django-cfg.readthedocs.io
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "django-cfg"
|
7
|
-
version = "1.1.
|
7
|
+
version = "1.1.52"
|
8
8
|
description = "🚀 Production-ready Django configuration framework with type-safe settings, smart automation, and modern developer experience"
|
9
9
|
readme = "README.md"
|
10
10
|
license = {text = "MIT"}
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/otp_service.py
RENAMED
@@ -6,7 +6,7 @@ from typing import Optional, Tuple
|
|
6
6
|
import re
|
7
7
|
|
8
8
|
from django_cfg.modules.django_telegram import DjangoTelegram
|
9
|
-
from django_cfg.modules.django_twilio import SimpleTwilioService,
|
9
|
+
from django_cfg.modules.django_twilio import SimpleTwilioService, send_whatsapp_otp_hybrid, verify_otp
|
10
10
|
from ..models import OTPSecret, CustomUser
|
11
11
|
from ..utils.notifications import AccountNotifications
|
12
12
|
from ..signals import notify_failed_otp_attempt
|
@@ -219,32 +219,36 @@ class OTPService:
|
|
219
219
|
user, otp_code, is_new_user=created, source_url=source_url, channel='email'
|
220
220
|
)
|
221
221
|
else: # phone channel
|
222
|
-
# Use
|
222
|
+
# Use hybrid WhatsApp OTP from twilio_service
|
223
|
+
success, message = send_whatsapp_otp_hybrid(cleaned_identifier, otp_code)
|
224
|
+
|
225
|
+
if not success:
|
226
|
+
logger.error(f"❌ Failed to send phone OTP to {cleaned_identifier[:8]}: {message}")
|
227
|
+
return False, "phone_send_failed"
|
228
|
+
|
229
|
+
logger.info(f"🎉 Phone OTP sent successfully to {cleaned_identifier[:8]}: {message}")
|
230
|
+
|
231
|
+
# Send telegram notification for admin
|
223
232
|
try:
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
233
|
+
# Extract method from message (e.g., "OTP sent via WhatsApp... (Direct WhatsApp)")
|
234
|
+
method_used = "Hybrid WhatsApp"
|
235
|
+
if "(Direct WhatsApp)" in message:
|
236
|
+
method_used = "Direct WhatsApp"
|
237
|
+
elif "(Verify API)" in message:
|
238
|
+
method_used = "Verify API"
|
230
239
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
"
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
)
|
242
|
-
except Exception as e:
|
243
|
-
logger.error(f"Failed to send telegram notification: {e}")
|
244
|
-
|
240
|
+
DjangoTelegram.send_info(
|
241
|
+
f"📱 Phone OTP Request ({method_used})",
|
242
|
+
{
|
243
|
+
"phone": cleaned_identifier,
|
244
|
+
"method": method_used,
|
245
|
+
"user_type": "New User" if created else "Existing User",
|
246
|
+
"source_url": source_url or "Direct",
|
247
|
+
"timestamp": timezone.now().strftime("%Y-%m-%d %H:%M:%S UTC")
|
248
|
+
}
|
249
|
+
)
|
245
250
|
except Exception as e:
|
246
|
-
logger.error(f"
|
247
|
-
return False, "phone_send_failed"
|
251
|
+
logger.error(f"Failed to send telegram notification: {e}")
|
248
252
|
|
249
253
|
return True, "success"
|
250
254
|
except Exception as e:
|
@@ -89,6 +89,10 @@ def __getattr__(name: str):
|
|
89
89
|
from django_cfg.modules.django_twilio.twilio_service import send_whatsapp_otp
|
90
90
|
return send_whatsapp_otp
|
91
91
|
|
92
|
+
elif name == "send_whatsapp_otp_hybrid":
|
93
|
+
from django_cfg.modules.django_twilio.twilio_service import send_whatsapp_otp_hybrid
|
94
|
+
return send_whatsapp_otp_hybrid
|
95
|
+
|
92
96
|
elif name == "send_sms_otp":
|
93
97
|
from django_cfg.modules.django_twilio.twilio_service import send_sms_otp
|
94
98
|
return send_sms_otp
|
@@ -144,6 +148,7 @@ __all__ = [
|
|
144
148
|
|
145
149
|
# OTP functions
|
146
150
|
"send_whatsapp_otp",
|
151
|
+
"send_whatsapp_otp_hybrid",
|
147
152
|
"send_email_otp",
|
148
153
|
"send_sms_otp",
|
149
154
|
"verify_otp",
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/twilio_service.py
RENAMED
@@ -238,7 +238,78 @@ class TwilioService(BaseModule):
|
|
238
238
|
|
239
239
|
# === OTP Methods (Twilio Verify API) ===
|
240
240
|
|
241
|
-
def
|
241
|
+
def send_whatsapp_otp_hybrid(self, phone_number: str, otp_code: str, fallback_to_sms: bool = True) -> Tuple[bool, str]:
|
242
|
+
"""
|
243
|
+
HYBRID APPROACH: Send OTP via Direct WhatsApp first, then fallback to Verify API.
|
244
|
+
|
245
|
+
Args:
|
246
|
+
phone_number: Phone number in E.164 format
|
247
|
+
otp_code: The OTP code to send
|
248
|
+
fallback_to_sms: Whether to fallback to SMS if WhatsApp fails
|
249
|
+
|
250
|
+
Returns:
|
251
|
+
Tuple[bool, str]: (success, message)
|
252
|
+
"""
|
253
|
+
success = False
|
254
|
+
final_message = ""
|
255
|
+
method_used = ""
|
256
|
+
|
257
|
+
# STEP 1: Try Direct WhatsApp with custom OTP
|
258
|
+
try:
|
259
|
+
from django_cfg.core.config import get_current_config
|
260
|
+
django_config = get_current_config()
|
261
|
+
site_name = django_config.project_name if django_config else "Django CFG"
|
262
|
+
|
263
|
+
# Create beautiful WhatsApp message
|
264
|
+
whatsapp_message = f"""🔐 *{site_name} Verification*
|
265
|
+
|
266
|
+
Your verification code: *{otp_code}*
|
267
|
+
|
268
|
+
⏰ Expires in 10 minutes
|
269
|
+
🔒 Keep this code secure
|
270
|
+
|
271
|
+
_Powered by {site_name}_"""
|
272
|
+
|
273
|
+
logger.info(f"🎯 Attempting Direct WhatsApp OTP to {self._mask_phone(phone_number)}...")
|
274
|
+
result = self.send_whatsapp_message(phone_number, whatsapp_message)
|
275
|
+
|
276
|
+
if result.get('sid'): # If we got a message SID, it was sent successfully
|
277
|
+
success = True
|
278
|
+
method_used = "Direct WhatsApp"
|
279
|
+
final_message = f"OTP sent via WhatsApp to {self._mask_phone(phone_number)}"
|
280
|
+
logger.info(f"✅ Direct WhatsApp OTP sent successfully: {result.get('sid', 'N/A')}")
|
281
|
+
else:
|
282
|
+
logger.warning(f"❌ Direct WhatsApp failed: No SID returned")
|
283
|
+
|
284
|
+
except Exception as e:
|
285
|
+
logger.warning(f"❌ Direct WhatsApp error: {e}")
|
286
|
+
|
287
|
+
# STEP 2: Fallback to Verify API if Direct WhatsApp failed
|
288
|
+
if not success:
|
289
|
+
try:
|
290
|
+
logger.info(f"🔄 Fallback: Trying Verify API for {self._mask_phone(phone_number)}...")
|
291
|
+
verify_success, verify_message = self.send_whatsapp_otp_verify(phone_number, fallback_to_sms)
|
292
|
+
|
293
|
+
if verify_success:
|
294
|
+
success = True
|
295
|
+
method_used = "Verify API"
|
296
|
+
final_message = verify_message
|
297
|
+
logger.info(f"✅ Verify API fallback successful")
|
298
|
+
else:
|
299
|
+
logger.error(f"❌ Verify API fallback failed: {verify_message}")
|
300
|
+
|
301
|
+
except Exception as e:
|
302
|
+
logger.error(f"❌ Verify API fallback error: {e}")
|
303
|
+
|
304
|
+
# STEP 3: Final check
|
305
|
+
if not success:
|
306
|
+
logger.error(f"❌ All WhatsApp methods failed for {self._mask_phone(phone_number)}")
|
307
|
+
return False, "All WhatsApp delivery methods failed"
|
308
|
+
|
309
|
+
logger.info(f"🎉 Phone OTP sent via {method_used} to {self._mask_phone(phone_number)}")
|
310
|
+
return True, f"{final_message} ({method_used})"
|
311
|
+
|
312
|
+
def send_whatsapp_otp_verify(self, phone_number: str, fallback_to_sms: bool = True) -> Tuple[bool, str]:
|
242
313
|
"""
|
243
314
|
Send OTP via WhatsApp using Twilio Verify API.
|
244
315
|
|
@@ -448,10 +519,16 @@ def send_sms(to: str, body: str, **kwargs) -> Dict[str, Any]:
|
|
448
519
|
return service.send_sms_message(to, body, **kwargs)
|
449
520
|
|
450
521
|
|
522
|
+
def send_whatsapp_otp_hybrid(phone_number: str, otp_code: str, fallback_to_sms: bool = True) -> Tuple[bool, str]:
|
523
|
+
"""Send WhatsApp OTP using hybrid approach (Direct WhatsApp first, then Verify API)."""
|
524
|
+
service = TwilioService()
|
525
|
+
return service.send_whatsapp_otp_hybrid(phone_number, otp_code, fallback_to_sms)
|
526
|
+
|
527
|
+
|
451
528
|
def send_whatsapp_otp(phone_number: str, fallback_to_sms: bool = True) -> Tuple[bool, str]:
|
452
|
-
"""Send WhatsApp OTP with optional SMS fallback."""
|
529
|
+
"""Send WhatsApp OTP with optional SMS fallback using Verify API only."""
|
453
530
|
service = TwilioService()
|
454
|
-
return service.
|
531
|
+
return service.send_whatsapp_otp_verify(phone_number, fallback_to_sms)
|
455
532
|
|
456
533
|
|
457
534
|
def send_sms_otp(phone_number: str) -> Tuple[bool, str]:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/registration_source.py
RENAMED
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/twilio_response.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/management/commands/test_otp.py
RENAMED
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/managers/user_manager.py
RENAMED
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/0001_initial.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/activity_service.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/base_email.txt
RENAMED
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/otp_email.html
RENAMED
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/otp_email.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/migrations/0001_initial.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/management/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/migrations/0001_initial.py
RENAMED
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/migrations/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/services/email_service.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/subscriptions.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/managers/message_manager.py
RENAMED
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/managers/ticket_manager.py
RENAMED
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/migrations/0001_initial.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/utils/support_email_service.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/templates/tasks/dashboard.html
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/check_settings.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/runserver_ngrok.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|