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.
Files changed (238) hide show
  1. {django_cfg-1.1.51 → django_cfg-1.1.52}/PKG-INFO +1 -1
  2. {django_cfg-1.1.51 → django_cfg-1.1.52}/pyproject.toml +1 -1
  3. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/__init__.py +1 -1
  4. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/otp_service.py +28 -24
  5. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/__init__.py +5 -0
  6. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/twilio_service.py +80 -3
  7. {django_cfg-1.1.51 → django_cfg-1.1.52}/.gitignore +0 -0
  8. {django_cfg-1.1.51 → django_cfg-1.1.52}/LICENSE +0 -0
  9. {django_cfg-1.1.51 → django_cfg-1.1.52}/MANIFEST.in +0 -0
  10. {django_cfg-1.1.51 → django_cfg-1.1.52}/README.md +0 -0
  11. {django_cfg-1.1.51 → django_cfg-1.1.52}/requirements-dev.txt +0 -0
  12. {django_cfg-1.1.51 → django_cfg-1.1.52}/requirements-test.txt +0 -0
  13. {django_cfg-1.1.51 → django_cfg-1.1.52}/requirements.txt +0 -0
  14. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/__init__.py +0 -0
  15. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/README.md +0 -0
  16. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/__init__.py +0 -0
  17. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/__init__.py +0 -0
  18. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/activity.py +0 -0
  19. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/filters.py +0 -0
  20. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/group.py +0 -0
  21. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/inlines.py +0 -0
  22. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/otp.py +0 -0
  23. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/registration_source.py +0 -0
  24. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/twilio_response.py +0 -0
  25. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/admin/user.py +0 -0
  26. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/apps.py +0 -0
  27. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/management/commands/test_otp.py +0 -0
  28. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/managers/__init__.py +0 -0
  29. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/managers/user_manager.py +0 -0
  30. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/0001_initial.py +0 -0
  31. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/0002_add_phone_otp_clean.py +0 -0
  32. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/0003_twilioresponse.py +0 -0
  33. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/migrations/__init__.py +0 -0
  34. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/models.py +0 -0
  35. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/__init__.py +0 -0
  36. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/otp.py +0 -0
  37. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/profile.py +0 -0
  38. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/serializers/webhook.py +0 -0
  39. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/__init__.py +0 -0
  40. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/services/activity_service.py +0 -0
  41. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/signals.py +0 -0
  42. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/base_email.html +0 -0
  43. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/base_email.txt +0 -0
  44. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/otp_email.html +0 -0
  45. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/otp_email.txt +0 -0
  46. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/welcome_email.html +0 -0
  47. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/templates/emails/welcome_email.txt +0 -0
  48. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/urls.py +0 -0
  49. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/utils/notifications.py +0 -0
  50. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/__init__.py +0 -0
  51. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/otp.py +0 -0
  52. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/profile.py +0 -0
  53. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/accounts/views/webhook.py +0 -0
  54. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/__init__.py +0 -0
  55. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/commands/__init__.py +0 -0
  56. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/commands/urls.py +0 -0
  57. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/commands/views.py +0 -0
  58. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/health/__init__.py +0 -0
  59. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/health/urls.py +0 -0
  60. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/api/health/views.py +0 -0
  61. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/README.md +0 -0
  62. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/__init__.py +0 -0
  63. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/admin.py +0 -0
  64. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/apps.py +0 -0
  65. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/migrations/0001_initial.py +0 -0
  66. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/migrations/__init__.py +0 -0
  67. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/models.py +0 -0
  68. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/serializers.py +0 -0
  69. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/signals.py +0 -0
  70. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/tests.py +0 -0
  71. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/urls.py +0 -0
  72. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/leads/views.py +0 -0
  73. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/README.md +0 -0
  74. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/__init__.py +0 -0
  75. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/admin.py +0 -0
  76. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/admin_filters.py +0 -0
  77. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/apps.py +0 -0
  78. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/management/__init__.py +0 -0
  79. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/management/commands/__init__.py +0 -0
  80. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/management/commands/test_newsletter.py +0 -0
  81. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/managers/README.md +0 -0
  82. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/managers/__init__.py +0 -0
  83. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/migrations/0001_initial.py +0 -0
  84. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/migrations/__init__.py +0 -0
  85. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/models.py +0 -0
  86. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/serializers.py +0 -0
  87. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/services/email_service.py +0 -0
  88. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/signals.py +0 -0
  89. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/urls.py +0 -0
  90. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/utils/__init__.py +0 -0
  91. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/__init__.py +0 -0
  92. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/campaigns.py +0 -0
  93. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/emails.py +0 -0
  94. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/newsletters.py +0 -0
  95. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/subscriptions.py +0 -0
  96. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/newsletter/views/tracking.py +0 -0
  97. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/__init__.py +0 -0
  98. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/admin.py +0 -0
  99. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/admin_filters.py +0 -0
  100. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/apps.py +0 -0
  101. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/managers/message_manager.py +0 -0
  102. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/managers/ticket_manager.py +0 -0
  103. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/migrations/0001_initial.py +0 -0
  104. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/migrations/0002_alter_message_ticket.py +0 -0
  105. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/migrations/__init__.py +0 -0
  106. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/models.py +0 -0
  107. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/serializers.py +0 -0
  108. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/signals.py +0 -0
  109. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/templates/support/chat/access_denied.html +0 -0
  110. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/templates/support/chat/ticket_chat.html +0 -0
  111. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/urls.py +0 -0
  112. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/utils/__init__.py +0 -0
  113. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/utils/support_email_service.py +0 -0
  114. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/__init__.py +0 -0
  115. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/admin.py +0 -0
  116. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/api.py +0 -0
  117. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/support/views/chat.py +0 -0
  118. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/__init__.py +0 -0
  119. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/admin.py +0 -0
  120. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/apps.py +0 -0
  121. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -0
  122. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/urls.py +0 -0
  123. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/tasks/views.py +0 -0
  124. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps/urls.py +0 -0
  125. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/apps.py +0 -0
  126. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/archive/django_sample.zip +0 -0
  127. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/README.md +0 -0
  128. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/__init__.py +0 -0
  129. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/commands/__init__.py +0 -0
  130. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/commands/create_project.py +0 -0
  131. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/commands/info.py +0 -0
  132. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/main.py +0 -0
  133. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/cli/utils.py +0 -0
  134. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/__init__.py +0 -0
  135. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/config.py +0 -0
  136. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/environment.py +0 -0
  137. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/generation.py +0 -0
  138. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/core/validation.py +0 -0
  139. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/exceptions.py +0 -0
  140. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/integration.py +0 -0
  141. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/__init__.py +0 -0
  142. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/__init__.py +0 -0
  143. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/check_settings.py +0 -0
  144. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/create_token.py +0 -0
  145. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/generate.py +0 -0
  146. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/list_urls.py +0 -0
  147. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/migrator.py +0 -0
  148. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/rundramatiq.py +0 -0
  149. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/runserver_ngrok.py +0 -0
  150. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/script.py +0 -0
  151. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/show_config.py +0 -0
  152. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/show_urls.py +0 -0
  153. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/superuser.py +0 -0
  154. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/task_clear.py +0 -0
  155. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/task_status.py +0 -0
  156. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/test_email.py +0 -0
  157. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/test_telegram.py +0 -0
  158. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/test_twilio.py +0 -0
  159. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/tree.py +0 -0
  160. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/management/commands/validate_config.py +0 -0
  161. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/middleware/README.md +0 -0
  162. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/middleware/__init__.py +0 -0
  163. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/middleware/user_activity.py +0 -0
  164. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/__init__.py +0 -0
  165. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/cache.py +0 -0
  166. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/constance.py +0 -0
  167. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/database.py +0 -0
  168. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/drf.py +0 -0
  169. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/jwt.py +0 -0
  170. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/limits.py +0 -0
  171. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/ngrok.py +0 -0
  172. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/revolution.py +0 -0
  173. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/services.py +0 -0
  174. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/tasks.py +0 -0
  175. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/models/unfold.py +0 -0
  176. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/__init__.py +0 -0
  177. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/base.py +0 -0
  178. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/README.md +0 -0
  179. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/__init__.py +0 -0
  180. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/cache.py +0 -0
  181. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/converter.py +0 -0
  182. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_currency/service.py +0 -0
  183. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_email.py +0 -0
  184. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/README.md +0 -0
  185. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/__init__.py +0 -0
  186. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/example.py +0 -0
  187. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/__init__.py +0 -0
  188. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/cache.py +0 -0
  189. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/client.py +0 -0
  190. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/llm/models_cache.py +0 -0
  191. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/service.py +0 -0
  192. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/translator/__init__.py +0 -0
  193. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/translator/cache.py +0 -0
  194. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_llm/translator/translator.py +0 -0
  195. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_logger.py +0 -0
  196. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_ngrok.py +0 -0
  197. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_tasks.py +0 -0
  198. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_telegram.py +0 -0
  199. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/README.md +0 -0
  200. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/exceptions.py +0 -0
  201. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/models.py +0 -0
  202. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/sendgrid_service.py +0 -0
  203. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/templates/guide.md +0 -0
  204. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/templates/sendgrid_otp_email.html +0 -0
  205. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/django_twilio/templates/sendgrid_test_data.json +0 -0
  206. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/logger.py +0 -0
  207. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/__init__.py +0 -0
  208. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/callbacks.py +0 -0
  209. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/dashboard.py +0 -0
  210. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/models.py +0 -0
  211. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/system_monitor.py +0 -0
  212. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/modules/unfold/tailwind.py +0 -0
  213. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/routers.py +0 -0
  214. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/__init__.py +0 -0
  215. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/index.html +0 -0
  216. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/layouts/dashboard_with_tabs.html +0 -0
  217. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/activity_tracker.html +0 -0
  218. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/charts_section.html +0 -0
  219. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/django_commands.html +0 -0
  220. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/quick_actions.html +0 -0
  221. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/recent_activity.html +0 -0
  222. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/recent_users_table.html +0 -0
  223. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/stats_cards.html +0 -0
  224. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/stats_tiles.html +0 -0
  225. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/system_health.html +0 -0
  226. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/system_metrics.html +0 -0
  227. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/components/user_permissions.html +0 -0
  228. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/app_stats_tab.html +0 -0
  229. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/commands_tab.html +0 -0
  230. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/overview_tab.html +0 -0
  231. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/stats_tab.html +0 -0
  232. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/tabs/users_tab.html +0 -0
  233. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/admin/snippets/zones/zones_table.html +0 -0
  234. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/templates/emails/base_email.html +0 -0
  235. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/utils/__init__.py +0 -0
  236. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/utils/path_resolution.py +0 -0
  237. {django_cfg-1.1.51 → django_cfg-1.1.52}/src/django_cfg/utils/smart_defaults.py +0 -0
  238. {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.51
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.51"
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"}
@@ -38,7 +38,7 @@ default_app_config = "django_cfg.apps.DjangoCfgConfig"
38
38
  from typing import TYPE_CHECKING
39
39
 
40
40
  # Version information
41
- __version__ = "1.1.51"
41
+ __version__ = "1.1.52"
42
42
  __author__ = "ReformsAI Team"
43
43
  __email__ = "info@reforms.ai"
44
44
  __license__ = "MIT"
@@ -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, send_whatsapp_otp, verify_otp
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 Twilio Verify API for professional OTP
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
- success, message = send_whatsapp_otp(cleaned_identifier)
225
- if not success:
226
- logger.error(f"Twilio Verify API failed: {message}")
227
- return False, "phone_send_failed"
228
-
229
- logger.info(f"Twilio Verify OTP sent to {cleaned_identifier}")
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
- # Still send telegram notification for admin
232
- try:
233
- DjangoTelegram.send_info(
234
- "📱 Phone OTP Request (Verify API)",
235
- {
236
- "phone": cleaned_identifier,
237
- "user_type": "New User" if created else "Existing User",
238
- "source_url": source_url or "Direct",
239
- "timestamp": timezone.now().strftime("%Y-%m-%d %H:%M:%S UTC")
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"Twilio Verify API error: {e}")
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",
@@ -238,7 +238,78 @@ class TwilioService(BaseModule):
238
238
 
239
239
  # === OTP Methods (Twilio Verify API) ===
240
240
 
241
- def send_whatsapp_otp(self, phone_number: str, fallback_to_sms: bool = True) -> Tuple[bool, str]:
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.send_whatsapp_otp(phone_number, fallback_to_sms)
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