django-cfg 1.4.20__py3-none-any.whl → 1.4.23__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (794) hide show
  1. django_cfg/__init__.py +4 -4
  2. django_cfg/apps/accounts/__init__.py +1 -1
  3. django_cfg/apps/accounts/__models.py +30 -29
  4. django_cfg/apps/accounts/admin/__init__.py +14 -3
  5. django_cfg/apps/accounts/admin/activity_admin.py +19 -19
  6. django_cfg/apps/accounts/admin/filters.py +7 -6
  7. django_cfg/apps/accounts/admin/group_admin.py +10 -16
  8. django_cfg/apps/accounts/admin/inlines.py +21 -19
  9. django_cfg/apps/accounts/admin/otp_admin.py +12 -12
  10. django_cfg/apps/accounts/admin/registration_admin.py +24 -24
  11. django_cfg/apps/accounts/admin/resources.py +49 -48
  12. django_cfg/apps/accounts/admin/twilio_admin.py +37 -37
  13. django_cfg/apps/accounts/admin/user_admin.py +45 -41
  14. django_cfg/apps/accounts/management/commands/otp_test.py +11 -11
  15. django_cfg/apps/accounts/managers/__init__.py +1 -1
  16. django_cfg/apps/accounts/managers/user_manager.py +6 -7
  17. django_cfg/apps/accounts/migrations/0001_initial.py +3 -2
  18. django_cfg/apps/accounts/models/__init__.py +15 -16
  19. django_cfg/apps/accounts/models/activity.py +5 -5
  20. django_cfg/apps/accounts/models/integrations.py +15 -15
  21. django_cfg/apps/accounts/models/registration.py +3 -2
  22. django_cfg/apps/accounts/models/user.py +3 -2
  23. django_cfg/apps/accounts/serializers/__init__.py +10 -3
  24. django_cfg/apps/accounts/serializers/otp.py +5 -4
  25. django_cfg/apps/accounts/serializers/profile.py +4 -5
  26. django_cfg/apps/accounts/serializers/webhook.py +13 -13
  27. django_cfg/apps/accounts/services/activity_service.py +13 -12
  28. django_cfg/apps/accounts/services/otp_service.py +16 -14
  29. django_cfg/apps/accounts/signals.py +18 -16
  30. django_cfg/apps/accounts/urls.py +10 -5
  31. django_cfg/apps/accounts/utils/notifications.py +22 -22
  32. django_cfg/apps/accounts/views/__init__.py +1 -1
  33. django_cfg/apps/accounts/views/otp.py +15 -14
  34. django_cfg/apps/accounts/views/profile.py +14 -10
  35. django_cfg/apps/accounts/views/webhook.py +46 -48
  36. django_cfg/apps/agents/__init__.py +3 -3
  37. django_cfg/apps/agents/admin/__init__.py +1 -1
  38. django_cfg/apps/agents/admin/execution_admin.py +68 -72
  39. django_cfg/apps/agents/admin/registry_admin.py +50 -54
  40. django_cfg/apps/agents/admin/toolsets_admin.py +63 -67
  41. django_cfg/apps/agents/apps.py +3 -3
  42. django_cfg/apps/agents/core/__init__.py +4 -4
  43. django_cfg/apps/agents/core/dependencies.py +24 -23
  44. django_cfg/apps/agents/core/django_agent.py +41 -39
  45. django_cfg/apps/agents/core/exceptions.py +12 -12
  46. django_cfg/apps/agents/core/models.py +16 -15
  47. django_cfg/apps/agents/core/orchestrator.py +58 -58
  48. django_cfg/apps/agents/examples/simple_example.py +24 -19
  49. django_cfg/apps/agents/integration/__init__.py +1 -1
  50. django_cfg/apps/agents/integration/middleware.py +12 -11
  51. django_cfg/apps/agents/integration/registry.py +52 -49
  52. django_cfg/apps/agents/integration/signals.py +5 -5
  53. django_cfg/apps/agents/management/commands/create_agent.py +39 -38
  54. django_cfg/apps/agents/management/commands/orchestrator_status.py +40 -39
  55. django_cfg/apps/agents/managers/__init__.py +8 -3
  56. django_cfg/apps/agents/managers/execution.py +42 -41
  57. django_cfg/apps/agents/managers/registry.py +40 -39
  58. django_cfg/apps/agents/managers/toolsets.py +87 -86
  59. django_cfg/apps/agents/migrations/0001_initial.py +2 -1
  60. django_cfg/apps/agents/models/__init__.py +2 -2
  61. django_cfg/apps/agents/models/execution.py +43 -42
  62. django_cfg/apps/agents/models/registry.py +46 -45
  63. django_cfg/apps/agents/models/toolsets.py +63 -62
  64. django_cfg/apps/agents/patterns/__init__.py +5 -5
  65. django_cfg/apps/agents/patterns/content_agents.py +17 -16
  66. django_cfg/apps/agents/toolsets/__init__.py +3 -3
  67. django_cfg/apps/agents/toolsets/cache_toolset.py +56 -55
  68. django_cfg/apps/agents/toolsets/django_toolset.py +43 -42
  69. django_cfg/apps/agents/toolsets/file_toolset.py +64 -63
  70. django_cfg/apps/agents/toolsets/orm_toolset.py +75 -74
  71. django_cfg/apps/agents/urls.py +3 -2
  72. django_cfg/apps/api/commands/urls.py +1 -0
  73. django_cfg/apps/api/commands/views.py +23 -26
  74. django_cfg/apps/api/endpoints/checker.py +5 -4
  75. django_cfg/apps/api/endpoints/drf_views.py +2 -2
  76. django_cfg/apps/api/endpoints/tests.py +6 -5
  77. django_cfg/apps/api/endpoints/urls.py +2 -1
  78. django_cfg/apps/api/endpoints/views.py +1 -0
  79. django_cfg/apps/api/health/drf_views.py +6 -6
  80. django_cfg/apps/api/health/urls.py +2 -1
  81. django_cfg/apps/api/health/views.py +41 -41
  82. django_cfg/{modules/django_ipc_client → apps/ipc}/__init__.py +6 -6
  83. django_cfg/apps/ipc/apps.py +28 -0
  84. django_cfg/apps/ipc/serializers/__init__.py +19 -0
  85. django_cfg/apps/ipc/serializers/serializers.py +229 -0
  86. django_cfg/apps/ipc/services/__init__.py +7 -0
  87. django_cfg/apps/ipc/services/client/__init__.py +23 -0
  88. django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/client.py +7 -6
  89. django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/exceptions.py +1 -1
  90. django_cfg/{modules/django_ipc_client/dashboard → apps/ipc/services}/monitor.py +23 -5
  91. 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
  92. django_cfg/{modules/django_ipc_client/dashboard/templates/django_ipc_dashboard → apps/ipc/templates/django_cfg_ipc}/base.html +5 -10
  93. django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +202 -0
  94. django_cfg/apps/ipc/urls.py +21 -0
  95. django_cfg/apps/ipc/urls_admin.py +20 -0
  96. django_cfg/apps/ipc/views/__init__.py +8 -0
  97. django_cfg/apps/ipc/views/dashboard.py +15 -0
  98. django_cfg/apps/ipc/views/viewsets.py +245 -0
  99. django_cfg/apps/knowbase/admin/__init__.py +2 -2
  100. django_cfg/apps/knowbase/admin/actions/__init__.py +1 -1
  101. django_cfg/apps/knowbase/admin/actions/visibility_actions.py +2 -1
  102. django_cfg/apps/knowbase/admin/archive_admin.py +81 -84
  103. django_cfg/apps/knowbase/admin/chat_admin.py +70 -72
  104. django_cfg/apps/knowbase/admin/document_admin.py +10 -11
  105. django_cfg/apps/knowbase/admin/external_data_admin.py +69 -71
  106. django_cfg/apps/knowbase/admin/helpers/__init__.py +1 -1
  107. django_cfg/apps/knowbase/admin/helpers/configs.py +2 -2
  108. django_cfg/apps/knowbase/admin/helpers/statistics.py +1 -1
  109. django_cfg/apps/knowbase/apps.py +13 -13
  110. django_cfg/apps/knowbase/config/__init__.py +7 -6
  111. django_cfg/apps/knowbase/config/constance_fields.py +14 -12
  112. django_cfg/apps/knowbase/config/constance_settings.py +32 -31
  113. django_cfg/apps/knowbase/config/settings.py +28 -28
  114. django_cfg/apps/knowbase/examples/external_data_usage.py +35 -32
  115. django_cfg/apps/knowbase/management/commands/knowbase_stats.py +33 -32
  116. django_cfg/apps/knowbase/management/commands/setup_knowbase.py +11 -13
  117. django_cfg/apps/knowbase/managers/__init__.py +2 -2
  118. django_cfg/apps/knowbase/managers/archive.py +86 -85
  119. django_cfg/apps/knowbase/managers/base.py +5 -5
  120. django_cfg/apps/knowbase/managers/chat.py +29 -28
  121. django_cfg/apps/knowbase/managers/document.py +39 -39
  122. django_cfg/apps/knowbase/managers/external_data.py +74 -73
  123. django_cfg/apps/knowbase/migrations/0001_initial.py +2 -1
  124. django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +2 -1
  125. django_cfg/apps/knowbase/migrations/0003_alter_documentarchive_archive_type.py +29 -0
  126. django_cfg/apps/knowbase/mixins/__init__.py +4 -4
  127. django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
  128. django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
  129. django_cfg/apps/knowbase/mixins/config.py +19 -18
  130. django_cfg/apps/knowbase/mixins/creator.py +7 -7
  131. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
  132. django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
  133. django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
  134. django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
  135. django_cfg/apps/knowbase/mixins/service.py +47 -45
  136. django_cfg/apps/knowbase/models/__init__.py +7 -7
  137. django_cfg/apps/knowbase/models/archive.py +72 -72
  138. django_cfg/apps/knowbase/models/base.py +12 -13
  139. django_cfg/apps/knowbase/models/chat.py +20 -19
  140. django_cfg/apps/knowbase/models/document.py +37 -35
  141. django_cfg/apps/knowbase/models/external_data.py +41 -42
  142. django_cfg/apps/knowbase/serializers/__init__.py +7 -7
  143. django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
  144. django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
  145. django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
  146. django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
  147. django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
  148. django_cfg/apps/knowbase/services/__init__.py +7 -7
  149. django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
  150. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
  151. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
  152. django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
  153. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
  154. django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
  155. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
  156. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
  157. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
  158. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
  159. django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
  160. django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
  161. django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
  162. django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
  163. django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
  164. django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
  165. django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
  166. django_cfg/apps/knowbase/services/base.py +11 -9
  167. django_cfg/apps/knowbase/services/chat_service.py +40 -39
  168. django_cfg/apps/knowbase/services/document_service.py +28 -27
  169. django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
  170. django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
  171. django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
  172. django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
  173. django_cfg/apps/knowbase/services/embedding/models.py +52 -51
  174. django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
  175. django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
  176. django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
  177. django_cfg/apps/knowbase/services/search_service.py +52 -49
  178. django_cfg/apps/knowbase/signals/__init__.py +2 -5
  179. django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
  180. django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
  181. django_cfg/apps/knowbase/signals/document_signals.py +22 -22
  182. django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
  183. django_cfg/apps/knowbase/tasks/__init__.py +6 -7
  184. django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
  185. django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
  186. django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
  187. django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
  188. django_cfg/apps/knowbase/urls.py +3 -2
  189. django_cfg/apps/knowbase/urls_admin.py +6 -3
  190. django_cfg/apps/knowbase/urls_system.py +4 -5
  191. django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
  192. django_cfg/apps/knowbase/utils/text_processing.py +76 -75
  193. django_cfg/apps/knowbase/utils/validation.py +9 -9
  194. django_cfg/apps/knowbase/views/__init__.py +5 -5
  195. django_cfg/apps/knowbase/views/archive_views.py +90 -87
  196. django_cfg/apps/knowbase/views/base.py +9 -12
  197. django_cfg/apps/knowbase/views/chat_views.py +35 -32
  198. django_cfg/apps/knowbase/views/document_views.py +27 -28
  199. django_cfg/apps/knowbase/views/public_views.py +19 -19
  200. django_cfg/apps/leads/admin/leads_admin.py +41 -45
  201. django_cfg/apps/leads/admin/resources.py +14 -14
  202. django_cfg/apps/leads/admin.py +7 -9
  203. django_cfg/apps/leads/apps.py +1 -1
  204. django_cfg/apps/leads/models.py +17 -17
  205. django_cfg/apps/leads/serializers.py +5 -4
  206. django_cfg/apps/leads/signals.py +7 -7
  207. django_cfg/apps/leads/tests.py +47 -47
  208. django_cfg/apps/leads/urls.py +2 -2
  209. django_cfg/apps/leads/views.py +11 -11
  210. django_cfg/apps/maintenance/__init__.py +3 -3
  211. django_cfg/apps/maintenance/admin/__init__.py +1 -1
  212. django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
  213. django_cfg/apps/maintenance/admin/log_admin.py +35 -37
  214. django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
  215. django_cfg/apps/maintenance/admin/site_admin.py +49 -52
  216. django_cfg/apps/maintenance/apps.py +2 -2
  217. django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
  218. django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
  219. django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
  220. django_cfg/apps/maintenance/managers/__init__.py +1 -1
  221. django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
  222. django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
  223. django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
  224. django_cfg/apps/maintenance/models/__init__.py +2 -2
  225. django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
  226. django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
  227. django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
  228. django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
  229. django_cfg/apps/maintenance/services/__init__.py +3 -3
  230. django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
  231. django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
  232. django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
  233. django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
  234. django_cfg/apps/maintenance/utils/__init__.py +1 -1
  235. django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
  236. django_cfg/apps/newsletter/admin/__init__.py +12 -16
  237. django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
  238. django_cfg/apps/newsletter/admin/resources.py +29 -29
  239. django_cfg/apps/newsletter/admin.py +39 -32
  240. django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
  241. django_cfg/apps/newsletter/managers/__init__.py +1 -1
  242. django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
  243. django_cfg/apps/newsletter/models.py +34 -33
  244. django_cfg/apps/newsletter/serializers.py +13 -13
  245. django_cfg/apps/newsletter/services/email_service.py +42 -40
  246. django_cfg/apps/newsletter/signals.py +4 -3
  247. django_cfg/apps/newsletter/urls.py +7 -7
  248. django_cfg/apps/newsletter/views/__init__.py +14 -19
  249. django_cfg/apps/newsletter/views/campaigns.py +19 -19
  250. django_cfg/apps/newsletter/views/emails.py +20 -20
  251. django_cfg/apps/newsletter/views/newsletters.py +5 -5
  252. django_cfg/apps/newsletter/views/subscriptions.py +24 -24
  253. django_cfg/apps/newsletter/views/tracking.py +6 -5
  254. django_cfg/apps/payments/admin/__init__.py +6 -5
  255. django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
  256. django_cfg/apps/payments/admin/balance_admin.py +41 -47
  257. django_cfg/apps/payments/admin/currencies_admin.py +60 -62
  258. django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
  259. django_cfg/apps/payments/admin/filters.py +59 -59
  260. django_cfg/apps/payments/admin/networks_admin.py +36 -50
  261. django_cfg/apps/payments/admin/payments_admin.py +47 -49
  262. django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
  263. django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
  264. django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
  265. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
  266. django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
  267. django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
  268. django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
  269. django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
  270. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
  271. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
  272. django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
  273. django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
  274. django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
  275. django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
  276. django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
  277. django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
  278. django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
  279. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
  280. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
  281. django_cfg/apps/payments/admin_interface/views/base.py +17 -19
  282. django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
  283. django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
  284. django_cfg/apps/payments/apps.py +7 -6
  285. django_cfg/apps/payments/config/__init__.py +4 -4
  286. django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
  287. django_cfg/apps/payments/config/helpers.py +14 -12
  288. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
  289. django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
  290. django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
  291. django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
  292. django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
  293. django_cfg/apps/payments/management/commands/test_providers.py +83 -84
  294. django_cfg/apps/payments/middleware/__init__.py +1 -1
  295. django_cfg/apps/payments/middleware/api_access.py +77 -78
  296. django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
  297. django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
  298. django_cfg/apps/payments/migrations/0001_initial.py +2 -1
  299. django_cfg/apps/payments/models/__init__.py +11 -12
  300. django_cfg/apps/payments/models/api_keys.py +29 -27
  301. django_cfg/apps/payments/models/balance.py +38 -38
  302. django_cfg/apps/payments/models/base.py +12 -11
  303. django_cfg/apps/payments/models/currencies.py +53 -52
  304. django_cfg/apps/payments/models/managers/__init__.py +13 -14
  305. django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
  306. django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
  307. django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
  308. django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
  309. django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
  310. django_cfg/apps/payments/models/payments.py +167 -73
  311. django_cfg/apps/payments/models/subscriptions.py +56 -54
  312. django_cfg/apps/payments/models/tariffs.py +35 -34
  313. django_cfg/apps/payments/services/__init__.py +33 -36
  314. django_cfg/apps/payments/services/cache/__init__.py +7 -1
  315. django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
  316. django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
  317. django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
  318. django_cfg/apps/payments/services/cache_service/keys.py +8 -8
  319. django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
  320. django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
  321. django_cfg/apps/payments/services/core/__init__.py +3 -3
  322. django_cfg/apps/payments/services/core/balance_service.py +69 -65
  323. django_cfg/apps/payments/services/core/base.py +25 -22
  324. django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
  325. django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
  326. django_cfg/apps/payments/services/core/currency_service.py +68 -66
  327. django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
  328. django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
  329. django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
  330. django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
  331. django_cfg/apps/payments/services/core/payment_service.py +10 -7
  332. django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
  333. django_cfg/apps/payments/services/core/subscription_service.py +77 -74
  334. django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
  335. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
  336. django_cfg/apps/payments/services/core/webhook_service.py +67 -63
  337. django_cfg/apps/payments/services/integrations/__init__.py +3 -3
  338. django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
  339. django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
  340. django_cfg/apps/payments/services/providers/base.py +59 -57
  341. django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
  342. django_cfg/apps/payments/services/providers/models/base.py +15 -15
  343. django_cfg/apps/payments/services/providers/models/providers.py +13 -12
  344. django_cfg/apps/payments/services/providers/models/universal.py +6 -5
  345. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
  346. django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
  347. django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
  348. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
  349. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
  350. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
  351. django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
  352. django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
  353. django_cfg/apps/payments/services/providers/registry.py +65 -63
  354. django_cfg/apps/payments/services/providers/sync_service.py +50 -50
  355. django_cfg/apps/payments/services/types/__init__.py +21 -22
  356. django_cfg/apps/payments/services/types/data.py +14 -13
  357. django_cfg/apps/payments/services/types/requests.py +21 -22
  358. django_cfg/apps/payments/services/types/responses.py +16 -15
  359. django_cfg/apps/payments/services/types/webhooks.py +30 -30
  360. django_cfg/apps/payments/signals/__init__.py +4 -6
  361. django_cfg/apps/payments/signals/api_key_signals.py +36 -35
  362. django_cfg/apps/payments/signals/balance_signals.py +28 -26
  363. django_cfg/apps/payments/signals/payment_signals.py +29 -28
  364. django_cfg/apps/payments/signals/subscription_signals.py +39 -38
  365. django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
  366. django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
  367. django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
  368. django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
  369. django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
  370. django_cfg/apps/payments/tasks/__init__.py +11 -12
  371. django_cfg/apps/payments/tasks/types.py +10 -9
  372. django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
  373. django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
  374. django_cfg/apps/payments/urls.py +31 -14
  375. django_cfg/apps/payments/urls_admin.py +10 -10
  376. django_cfg/apps/payments/views/api/__init__.py +32 -33
  377. django_cfg/apps/payments/views/api/api_keys.py +62 -62
  378. django_cfg/apps/payments/views/api/balances.py +63 -64
  379. django_cfg/apps/payments/views/api/base.py +52 -52
  380. django_cfg/apps/payments/views/api/currencies.py +75 -63
  381. django_cfg/apps/payments/views/api/payments.py +73 -74
  382. django_cfg/apps/payments/views/api/subscriptions.py +71 -72
  383. django_cfg/apps/payments/views/api/webhooks.py +85 -84
  384. django_cfg/apps/payments/views/overview/__init__.py +7 -7
  385. django_cfg/apps/payments/views/overview/serializers.py +13 -14
  386. django_cfg/apps/payments/views/overview/services.py +66 -67
  387. django_cfg/apps/payments/views/overview/urls.py +2 -1
  388. django_cfg/apps/payments/views/overview/views.py +31 -31
  389. django_cfg/apps/payments/views/serializers/__init__.py +35 -36
  390. django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
  391. django_cfg/apps/payments/views/serializers/balances.py +34 -33
  392. django_cfg/apps/payments/views/serializers/currencies.py +36 -34
  393. django_cfg/apps/payments/views/serializers/payments.py +48 -47
  394. django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
  395. django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
  396. django_cfg/apps/support/admin/__init__.py +3 -3
  397. django_cfg/apps/support/admin/resources.py +26 -26
  398. django_cfg/apps/support/admin/support_admin.py +44 -48
  399. django_cfg/apps/support/admin.py +16 -15
  400. django_cfg/apps/support/apps.py +1 -1
  401. django_cfg/apps/support/managers/message_manager.py +4 -4
  402. django_cfg/apps/support/managers/ticket_manager.py +13 -12
  403. django_cfg/apps/support/migrations/0001_initial.py +2 -1
  404. django_cfg/apps/support/models.py +3 -1
  405. django_cfg/apps/support/serializers.py +4 -2
  406. django_cfg/apps/support/signals.py +12 -10
  407. django_cfg/apps/support/urls.py +4 -3
  408. django_cfg/apps/support/utils/support_email_service.py +11 -9
  409. django_cfg/apps/support/views/__init__.py +3 -3
  410. django_cfg/apps/support/views/admin.py +9 -9
  411. django_cfg/apps/support/views/api.py +12 -13
  412. django_cfg/apps/support/views/chat.py +14 -14
  413. django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
  414. django_cfg/apps/tasks/apps.py +2 -2
  415. django_cfg/apps/tasks/serializers.py +6 -6
  416. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
  417. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
  418. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
  419. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
  420. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
  421. django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
  422. django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
  423. django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
  424. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
  425. django_cfg/apps/tasks/urls.py +3 -2
  426. django_cfg/apps/tasks/urls_admin.py +1 -0
  427. django_cfg/apps/tasks/utils/simulator.py +49 -52
  428. django_cfg/apps/tasks/views/api.py +75 -73
  429. django_cfg/apps/tasks/views/dashboard.py +5 -4
  430. django_cfg/apps/urls.py +20 -11
  431. django_cfg/apps.py +6 -5
  432. django_cfg/cli/commands/create_project.py +7 -6
  433. django_cfg/cli/commands/info.py +25 -25
  434. django_cfg/cli/utils.py +27 -27
  435. django_cfg/config.py +1 -1
  436. django_cfg/core/__init__.py +8 -8
  437. django_cfg/core/base/config_model.py +13 -12
  438. django_cfg/core/builders/apps_builder.py +2 -2
  439. django_cfg/core/builders/middleware_builder.py +1 -1
  440. django_cfg/core/builders/security_builder.py +1 -1
  441. django_cfg/core/config.py +2 -2
  442. django_cfg/core/environment/detector.py +27 -28
  443. django_cfg/core/exceptions.py +1 -1
  444. django_cfg/core/generation/core_generators/settings.py +1 -1
  445. django_cfg/core/generation/core_generators/static.py +11 -5
  446. django_cfg/core/generation/core_generators/templates.py +1 -1
  447. django_cfg/core/generation/data_generators/__init__.py +1 -1
  448. django_cfg/core/generation/data_generators/cache.py +1 -1
  449. django_cfg/core/generation/data_generators/database.py +1 -1
  450. django_cfg/core/generation/generation.py +1 -3
  451. django_cfg/core/generation/integration_generators/__init__.py +2 -2
  452. django_cfg/core/generation/integration_generators/api.py +12 -2
  453. django_cfg/core/generation/integration_generators/sessions.py +1 -1
  454. django_cfg/core/generation/integration_generators/tailwind.py +1 -1
  455. django_cfg/core/generation/integration_generators/tasks.py +1 -1
  456. django_cfg/core/generation/integration_generators/third_party.py +1 -1
  457. django_cfg/core/generation/orchestrator.py +1 -1
  458. django_cfg/core/generation/protocols.py +1 -1
  459. django_cfg/core/generation/utility_generators/__init__.py +1 -1
  460. django_cfg/core/generation/utility_generators/email.py +1 -1
  461. django_cfg/core/generation/utility_generators/i18n.py +1 -1
  462. django_cfg/core/generation/utility_generators/limits.py +1 -1
  463. django_cfg/core/generation/utility_generators/logging.py +1 -1
  464. django_cfg/core/generation/utility_generators/security.py +1 -1
  465. django_cfg/core/generation/utils/helpers.py +1 -1
  466. django_cfg/core/integration/__init__.py +5 -5
  467. django_cfg/core/integration/commands_collector.py +38 -39
  468. django_cfg/core/integration/display/__init__.py +2 -2
  469. django_cfg/core/integration/display/base.py +30 -30
  470. django_cfg/core/integration/display/ngrok.py +35 -36
  471. django_cfg/core/integration/display/startup.py +149 -139
  472. django_cfg/core/integration/url_integration.py +10 -10
  473. django_cfg/core/integration/version_checker.py +20 -19
  474. django_cfg/core/services/config_service.py +4 -4
  475. django_cfg/core/state/__init__.py +1 -1
  476. django_cfg/core/state/registry.py +1 -1
  477. django_cfg/core/types/__init__.py +8 -1
  478. django_cfg/core/validation.py +36 -39
  479. django_cfg/management/commands/check_endpoints.py +3 -1
  480. django_cfg/management/commands/check_settings.py +3 -1
  481. django_cfg/management/commands/clear_constance.py +3 -1
  482. django_cfg/management/commands/create_token.py +3 -1
  483. django_cfg/management/commands/generate_clients.py +3 -1
  484. django_cfg/management/commands/migrate_all.py +3 -1
  485. django_cfg/management/commands/rundramatiq.py +3 -1
  486. django_cfg/management/commands/rundramatiq_simulator.py +3 -1
  487. django_cfg/management/commands/runserver_ngrok.py +3 -1
  488. django_cfg/management/commands/show_config.py +3 -1
  489. django_cfg/management/commands/superuser.py +3 -1
  490. django_cfg/management/commands/task_clear.py +3 -1
  491. django_cfg/management/commands/task_status.py +3 -1
  492. django_cfg/management/commands/test_email.py +3 -1
  493. django_cfg/management/commands/test_telegram.py +3 -1
  494. django_cfg/management/commands/test_twilio.py +3 -1
  495. django_cfg/management/commands/validate_openapi.py +3 -1
  496. django_cfg/middleware/pagination.py +8 -8
  497. django_cfg/middleware/public_endpoints.py +24 -23
  498. django_cfg/middleware/user_activity.py +27 -25
  499. django_cfg/models/__init__.py +19 -20
  500. django_cfg/models/api/__init__.py +4 -4
  501. django_cfg/models/api/config.py +23 -21
  502. django_cfg/models/api/cors.py +17 -16
  503. django_cfg/models/api/drf/__init__.py +1 -1
  504. django_cfg/models/api/drf/config.py +2 -1
  505. django_cfg/models/api/drf/redoc.py +2 -1
  506. django_cfg/models/api/drf/spectacular.py +4 -2
  507. django_cfg/models/api/drf/swagger.py +2 -1
  508. django_cfg/models/api/jwt.py +37 -36
  509. django_cfg/models/api/keys.py +13 -12
  510. django_cfg/models/api/limits.py +31 -30
  511. django_cfg/models/base/config.py +40 -41
  512. django_cfg/models/base/module.py +8 -8
  513. django_cfg/models/django/__init__.py +1 -1
  514. django_cfg/models/django/constance.py +8 -7
  515. django_cfg/models/django/environment.py +5 -3
  516. django_cfg/models/django/openapi.py +6 -16
  517. django_cfg/models/django/revolution_legacy.py +17 -16
  518. django_cfg/models/infrastructure/__init__.py +1 -1
  519. django_cfg/models/infrastructure/cache.py +46 -45
  520. django_cfg/models/infrastructure/database/config.py +4 -6
  521. django_cfg/models/infrastructure/database/converters.py +1 -1
  522. django_cfg/models/infrastructure/database/parsers.py +1 -1
  523. django_cfg/models/infrastructure/database/validators.py +1 -1
  524. django_cfg/models/infrastructure/logging.py +59 -57
  525. django_cfg/models/infrastructure/security.py +26 -24
  526. django_cfg/models/ngrok/auth.py +2 -1
  527. django_cfg/models/ngrok/config.py +3 -2
  528. django_cfg/models/ngrok/tunnel.py +2 -1
  529. django_cfg/models/payments/__init__.py +1 -1
  530. django_cfg/models/payments/api_keys.py +3 -1
  531. django_cfg/models/payments/config.py +4 -1
  532. django_cfg/models/payments/providers/base.py +2 -1
  533. django_cfg/models/payments/providers/nowpayments.py +3 -1
  534. django_cfg/models/services/__init__.py +1 -1
  535. django_cfg/models/services/base.py +2 -1
  536. django_cfg/models/services/email.py +28 -26
  537. django_cfg/models/services/telegram.py +2 -1
  538. django_cfg/models/tasks/__init__.py +2 -2
  539. django_cfg/models/tasks/backends.py +4 -3
  540. django_cfg/models/tasks/config.py +6 -4
  541. django_cfg/models/tasks/utils.py +3 -3
  542. django_cfg/modules/base.py +18 -17
  543. django_cfg/modules/django_admin/__init__.py +14 -15
  544. django_cfg/modules/django_admin/decorators/__init__.py +1 -1
  545. django_cfg/modules/django_admin/decorators/actions.py +8 -7
  546. django_cfg/modules/django_admin/decorators/display.py +9 -7
  547. django_cfg/modules/django_admin/icons/__init__.py +1 -1
  548. django_cfg/modules/django_admin/icons/constants.py +27 -27
  549. django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
  550. django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
  551. django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
  552. django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
  553. django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
  554. django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
  555. django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
  556. django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
  557. django_cfg/modules/django_admin/management/commands/script.py +58 -60
  558. django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
  559. django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
  560. django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
  561. django_cfg/modules/django_admin/management/commands/tree.py +50 -54
  562. django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
  563. django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
  564. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
  565. django_cfg/modules/django_admin/models/__init__.py +4 -4
  566. django_cfg/modules/django_admin/models/action_models.py +3 -1
  567. django_cfg/modules/django_admin/models/badge_models.py +4 -2
  568. django_cfg/modules/django_admin/models/base.py +3 -3
  569. django_cfg/modules/django_admin/models/display_models.py +1 -0
  570. django_cfg/modules/django_admin/utils/badges.py +27 -26
  571. django_cfg/modules/django_admin/utils/displays.py +49 -49
  572. django_cfg/modules/django_client/apps.py +21 -3
  573. django_cfg/modules/django_client/core/__init__.py +9 -10
  574. django_cfg/modules/django_client/core/archive/manager.py +2 -2
  575. django_cfg/modules/django_client/core/cli/main.py +1 -3
  576. django_cfg/modules/django_client/core/config/config.py +3 -1
  577. django_cfg/modules/django_client/core/config/group.py +1 -0
  578. django_cfg/modules/django_client/core/config/service.py +2 -1
  579. django_cfg/modules/django_client/core/generator/__init__.py +1 -1
  580. django_cfg/modules/django_client/core/generator/base.py +2 -2
  581. django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
  582. django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
  583. django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
  584. django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
  585. django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
  586. django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
  587. django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
  588. django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
  589. django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
  590. django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
  591. django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
  592. django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
  593. django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
  594. django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
  595. django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
  596. django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
  597. django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
  598. django_cfg/modules/django_client/core/groups/__init__.py +1 -1
  599. django_cfg/modules/django_client/core/groups/detector.py +2 -1
  600. django_cfg/modules/django_client/core/groups/manager.py +2 -1
  601. django_cfg/modules/django_client/core/ir/schema.py +1 -1
  602. django_cfg/modules/django_client/core/parser/base.py +0 -2
  603. django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
  604. django_cfg/modules/django_client/core/validation/__init__.py +1 -1
  605. django_cfg/modules/django_client/core/validation/fixer.py +1 -2
  606. django_cfg/modules/django_client/core/validation/reporter.py +2 -2
  607. django_cfg/modules/django_client/core/validation/safety.py +1 -1
  608. django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
  609. django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
  610. django_cfg/modules/django_client/spectacular/__init__.py +1 -1
  611. django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
  612. django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
  613. django_cfg/modules/django_client/spectacular/schema.py +5 -5
  614. django_cfg/modules/django_client/system/__init__.py +24 -0
  615. django_cfg/modules/django_client/system/base_generator.py +123 -0
  616. django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
  617. django_cfg/modules/django_client/system/mjs_generator.py +219 -0
  618. django_cfg/modules/django_client/system/schema_parser.py +195 -0
  619. django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
  620. django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
  621. django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
  622. django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
  623. django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
  624. django_cfg/modules/django_client/urls.py +3 -2
  625. django_cfg/modules/django_currency/__init__.py +17 -18
  626. django_cfg/modules/django_currency/clients/__init__.py +2 -2
  627. django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
  628. django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
  629. django_cfg/modules/django_currency/core/__init__.py +7 -13
  630. django_cfg/modules/django_currency/core/converter.py +25 -24
  631. django_cfg/modules/django_currency/core/models.py +9 -8
  632. django_cfg/modules/django_currency/database/__init__.py +4 -4
  633. django_cfg/modules/django_currency/database/database_loader.py +65 -66
  634. django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
  635. django_cfg/modules/django_currency/utils/cache.py +10 -11
  636. django_cfg/modules/django_dashboard/__init__.py +4 -5
  637. django_cfg/modules/django_dashboard/components.py +11 -7
  638. django_cfg/modules/django_dashboard/debug.py +1 -3
  639. django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
  640. django_cfg/modules/django_dashboard/sections/base.py +2 -1
  641. django_cfg/modules/django_dashboard/sections/commands.py +3 -2
  642. django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
  643. django_cfg/modules/django_dashboard/sections/overview.py +13 -9
  644. django_cfg/modules/django_dashboard/sections/stats.py +2 -2
  645. django_cfg/modules/django_dashboard/sections/system.py +2 -1
  646. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
  647. django_cfg/modules/django_email/management/commands/test_email.py +8 -7
  648. django_cfg/modules/django_email/service.py +5 -4
  649. django_cfg/modules/django_health/service.py +46 -44
  650. django_cfg/modules/django_import_export/__init__.py +7 -3
  651. django_cfg/modules/django_llm/__init__.py +3 -2
  652. django_cfg/modules/django_llm/example.py +58 -56
  653. django_cfg/modules/django_llm/llm/__init__.py +1 -1
  654. django_cfg/modules/django_llm/llm/cache.py +21 -20
  655. django_cfg/modules/django_llm/llm/client.py +9 -9
  656. django_cfg/modules/django_llm/llm/costs.py +14 -14
  657. django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
  658. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
  659. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
  660. django_cfg/modules/django_llm/llm/extractor.py +8 -8
  661. django_cfg/modules/django_llm/llm/models.py +5 -5
  662. django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
  663. django_cfg/modules/django_llm/llm/models_cache.py +91 -92
  664. django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
  665. django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
  666. django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
  667. django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
  668. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
  669. django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
  670. django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
  671. django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
  672. django_cfg/modules/django_llm/translator/__init__.py +1 -1
  673. django_cfg/modules/django_llm/translator/cache.py +36 -35
  674. django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
  675. django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
  676. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
  677. django_cfg/modules/django_llm/translator/translator.py +5 -4
  678. django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
  679. django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
  680. django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
  681. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
  682. django_cfg/modules/django_logging/__init__.py +1 -1
  683. django_cfg/modules/django_logging/django_logger.py +33 -34
  684. django_cfg/modules/django_logging/logger.py +3 -7
  685. django_cfg/modules/django_ngrok/__init__.py +7 -7
  686. django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
  687. django_cfg/modules/django_ngrok/service.py +33 -32
  688. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
  689. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
  690. django_cfg/modules/django_tasks/__init__.py +5 -5
  691. django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
  692. django_cfg/modules/django_tasks/factory.py +1 -1
  693. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
  694. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
  695. django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
  696. django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
  697. django_cfg/modules/django_tasks/service.py +4 -3
  698. django_cfg/modules/django_tasks/settings.py +1 -1
  699. django_cfg/modules/django_telegram/__init__.py +4 -4
  700. django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
  701. django_cfg/modules/django_telegram/service.py +4 -3
  702. django_cfg/modules/django_telegram/utils.py +1 -1
  703. django_cfg/modules/django_twilio/__init__.py +15 -16
  704. django_cfg/modules/django_twilio/_imports.py +1 -1
  705. django_cfg/modules/django_twilio/base.py +9 -5
  706. django_cfg/modules/django_twilio/email_otp.py +4 -3
  707. django_cfg/modules/django_twilio/exceptions.py +36 -36
  708. django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
  709. django_cfg/modules/django_twilio/models.py +54 -53
  710. django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
  711. django_cfg/modules/django_twilio/simple_service.py +42 -41
  712. django_cfg/modules/django_twilio/sms.py +1 -0
  713. django_cfg/modules/django_twilio/twilio_service.py +79 -83
  714. django_cfg/modules/django_twilio/unified.py +6 -5
  715. django_cfg/modules/django_twilio/utils.py +2 -3
  716. django_cfg/modules/django_twilio/whatsapp.py +3 -2
  717. django_cfg/modules/django_unfold/__init__.py +7 -6
  718. django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
  719. django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
  720. django_cfg/modules/django_unfold/callbacks/base.py +9 -8
  721. django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
  722. django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
  723. django_cfg/modules/django_unfold/callbacks/main.py +27 -27
  724. django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
  725. django_cfg/modules/django_unfold/callbacks/system.py +5 -5
  726. django_cfg/modules/django_unfold/callbacks/users.py +4 -4
  727. django_cfg/modules/django_unfold/dashboard.py +29 -29
  728. django_cfg/modules/django_unfold/models/__init__.py +23 -8
  729. django_cfg/modules/django_unfold/models/config.py +84 -81
  730. django_cfg/modules/django_unfold/models/dashboard.py +20 -19
  731. django_cfg/modules/django_unfold/models/dropdown.py +6 -4
  732. django_cfg/modules/django_unfold/models/navigation.py +6 -4
  733. django_cfg/modules/django_unfold/models/tabs.py +4 -3
  734. django_cfg/modules/django_unfold/models.py +2 -3
  735. django_cfg/modules/django_unfold/system_monitor.py +27 -25
  736. django_cfg/modules/django_unfold/tailwind.py +12 -14
  737. django_cfg/modules/django_unfold/utils.py +7 -6
  738. django_cfg/pyproject.toml +1 -1
  739. django_cfg/registry/__init__.py +3 -3
  740. django_cfg/registry/core.py +8 -8
  741. django_cfg/registry/modules.py +2 -2
  742. django_cfg/registry/services.py +2 -2
  743. django_cfg/registry/third_party.py +3 -3
  744. django_cfg/routing/__init__.py +3 -3
  745. django_cfg/routing/callbacks.py +27 -26
  746. django_cfg/routing/routers.py +2 -2
  747. django_cfg/static/js/api/accounts/client.mjs +69 -0
  748. django_cfg/static/js/api/accounts/index.mjs +13 -0
  749. django_cfg/static/js/api/base.mjs +166 -0
  750. django_cfg/static/js/api/index.mjs +100 -0
  751. django_cfg/static/js/api/ipc/client.mjs +74 -0
  752. django_cfg/static/js/api/ipc/index.mjs +13 -0
  753. django_cfg/static/js/api/leads/client.mjs +71 -0
  754. django_cfg/static/js/api/leads/index.mjs +13 -0
  755. django_cfg/static/js/api/newsletter/client.mjs +109 -0
  756. django_cfg/static/js/api/newsletter/index.mjs +13 -0
  757. django_cfg/static/js/api/payments/client.mjs +1264 -0
  758. django_cfg/static/js/api/payments/index.mjs +13 -0
  759. django_cfg/static/js/api/support/client.mjs +84 -0
  760. django_cfg/static/js/api/support/index.mjs +13 -0
  761. django_cfg/static/js/api/tasks/client.mjs +74 -0
  762. django_cfg/static/js/api/tasks/index.mjs +13 -0
  763. django_cfg/static/js/api/types.mjs +729 -0
  764. django_cfg/static/js/api-loader.mjs +169 -0
  765. django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
  766. django_cfg/templatetags/django_cfg.py +4 -4
  767. django_cfg/utils/path_resolution.py +49 -50
  768. django_cfg/utils/smart_defaults.py +27 -29
  769. django_cfg/utils/version_check.py +14 -14
  770. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/METADATA +1 -1
  771. django_cfg-1.4.23.dist-info/RECORD +1137 -0
  772. django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
  773. django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
  774. django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
  775. django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
  776. django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
  777. django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
  778. django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
  779. django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
  780. django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
  781. django_cfg/modules/django_rpc_old/POETRY.md +0 -344
  782. django_cfg/modules/django_rpc_old/README.md +0 -397
  783. django_cfg/modules/django_rpc_old/TESTING.md +0 -358
  784. django_cfg/modules/django_rpc_old/__init__.py +0 -39
  785. django_cfg/modules/django_rpc_old/client.py +0 -531
  786. django_cfg/modules/django_rpc_old/config.py +0 -279
  787. django_cfg/modules/django_rpc_old/exceptions.py +0 -172
  788. django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
  789. django_cfg-1.4.20.dist-info/RECORD +0 -1110
  790. /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
  791. /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
  792. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/WHEEL +0 -0
  793. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/entry_points.txt +0 -0
  794. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -2,10 +2,10 @@
2
2
  DRF Serializers for newsletter application.
3
3
  """
4
4
 
5
- from rest_framework import serializers
6
5
  from django.contrib.auth import get_user_model
6
+ from rest_framework import serializers
7
7
 
8
- from .models import Newsletter, NewsletterSubscription, NewsletterCampaign, EmailLog
8
+ from .models import EmailLog, Newsletter, NewsletterCampaign, NewsletterSubscription
9
9
 
10
10
  User = get_user_model()
11
11
 
@@ -14,7 +14,7 @@ class NewsletterSerializer(serializers.ModelSerializer):
14
14
  """Serializer for Newsletter model."""
15
15
 
16
16
  subscribers_count = serializers.IntegerField(read_only=True)
17
-
17
+
18
18
  class Meta:
19
19
  model = Newsletter
20
20
  fields = [
@@ -26,10 +26,10 @@ class NewsletterSerializer(serializers.ModelSerializer):
26
26
 
27
27
  class NewsletterSubscriptionSerializer(serializers.ModelSerializer):
28
28
  """Serializer for NewsletterSubscription model."""
29
-
29
+
30
30
  newsletter_title = serializers.CharField(source='newsletter.title', read_only=True)
31
31
  user_email = serializers.CharField(source='user.email', read_only=True)
32
-
32
+
33
33
  class Meta:
34
34
  model = NewsletterSubscription
35
35
  fields = [
@@ -43,20 +43,20 @@ class NewsletterSubscriptionSerializer(serializers.ModelSerializer):
43
43
 
44
44
  class SubscribeSerializer(serializers.Serializer):
45
45
  """Simple serializer for newsletter subscription."""
46
-
46
+
47
47
  newsletter_id = serializers.IntegerField()
48
48
  email = serializers.EmailField()
49
49
 
50
50
 
51
51
  class UnsubscribeSerializer(serializers.Serializer):
52
52
  """Simple serializer for unsubscribe."""
53
-
53
+
54
54
  subscription_id = serializers.IntegerField()
55
55
 
56
56
 
57
57
  class TestEmailSerializer(serializers.Serializer):
58
58
  """Simple serializer for test email."""
59
-
59
+
60
60
  email = serializers.EmailField()
61
61
  subject = serializers.CharField(max_length=255, default="Django CFG Newsletter Test")
62
62
  message = serializers.CharField(default="This is a test email from Django CFG Newsletter.")
@@ -64,9 +64,9 @@ class TestEmailSerializer(serializers.Serializer):
64
64
 
65
65
  class NewsletterCampaignSerializer(serializers.ModelSerializer):
66
66
  """Serializer for NewsletterCampaign model."""
67
-
67
+
68
68
  newsletter_title = serializers.CharField(source='newsletter.title', read_only=True)
69
-
69
+
70
70
  class Meta:
71
71
  model = NewsletterCampaign
72
72
  fields = [
@@ -81,16 +81,16 @@ class NewsletterCampaignSerializer(serializers.ModelSerializer):
81
81
 
82
82
  class SendCampaignSerializer(serializers.Serializer):
83
83
  """Simple serializer for sending campaign."""
84
-
84
+
85
85
  campaign_id = serializers.IntegerField()
86
86
 
87
87
 
88
88
  class EmailLogSerializer(serializers.ModelSerializer):
89
89
  """Serializer for EmailLog model."""
90
-
90
+
91
91
  user_email = serializers.CharField(source='user.email', read_only=True)
92
92
  newsletter_title = serializers.CharField(source='newsletter.title', read_only=True)
93
-
93
+
94
94
  class Meta:
95
95
  model = EmailLog
96
96
  fields = [
@@ -5,12 +5,14 @@ Uses the built-in DjangoEmailService for sending emails with proper logging.
5
5
  """
6
6
 
7
7
  import logging
8
- from typing import List, Optional, Dict, Any
8
+ from typing import Any, Dict, List, Optional
9
+
9
10
  from django.contrib.auth import get_user_model
10
11
  from django.utils import timezone
11
12
 
12
13
  from django_cfg.modules.django_email import DjangoEmailService
13
- from ..models import Newsletter, NewsletterSubscription, EmailLog
14
+
15
+ from ..models import EmailLog, Newsletter, NewsletterSubscription
14
16
 
15
17
  User = get_user_model()
16
18
  logger = logging.getLogger(__name__)
@@ -18,16 +20,16 @@ logger = logging.getLogger(__name__)
18
20
 
19
21
  class NewsletterEmailService:
20
22
  """Email service for newsletter application using DjangoEmailService."""
21
-
23
+
22
24
  def __init__(self):
23
25
  """Initialize the email service."""
24
26
  self.email_service = DjangoEmailService()
25
-
27
+
26
28
  def _create_email_log(
27
- self,
28
- recipient: str,
29
- subject: str,
30
- status: str,
29
+ self,
30
+ recipient: str,
31
+ subject: str,
32
+ status: str,
31
33
  newsletter: Optional[Newsletter] = None,
32
34
  campaign = None
33
35
  ) -> EmailLog:
@@ -46,14 +48,14 @@ class NewsletterEmailService:
46
48
  """
47
49
  try:
48
50
  from django.utils import timezone
49
-
51
+
50
52
  # Try to find user by email
51
53
  user = None
52
54
  try:
53
55
  user = User.objects.get(email=recipient)
54
56
  except User.DoesNotExist:
55
57
  pass
56
-
58
+
57
59
  log_data = {
58
60
  'user': user,
59
61
  'newsletter': newsletter,
@@ -61,18 +63,18 @@ class NewsletterEmailService:
61
63
  'recipient': recipient,
62
64
  'subject': subject,
63
65
  'status': status,
64
- 'body': f"Newsletter email sent via campaign"
66
+ 'body': "Newsletter email sent via campaign"
65
67
  }
66
-
68
+
67
69
  # Add sent_at for successful emails
68
70
  if status == EmailLog.EmailLogStatus.SENT:
69
71
  log_data['sent_at'] = timezone.now()
70
-
72
+
71
73
  return EmailLog.objects.create(**log_data)
72
74
  except Exception as e:
73
75
  logger.error(f"Failed to create email log: {e}")
74
76
  raise
75
-
77
+
76
78
  def send_newsletter_email(
77
79
  self,
78
80
  newsletter: Newsletter,
@@ -133,7 +135,7 @@ class NewsletterEmailService:
133
135
  'sent_count': 0,
134
136
  'failed_count': 0
135
137
  }
136
-
138
+
137
139
  if not emails:
138
140
  return {
139
141
  'success': False,
@@ -141,7 +143,7 @@ class NewsletterEmailService:
141
143
  'sent_count': 0,
142
144
  'failed_count': 0
143
145
  }
144
-
146
+
145
147
  # Use the optimized send_bulk_email method with tracking
146
148
  result = self.send_bulk_email(
147
149
  recipients=emails,
@@ -157,17 +159,17 @@ class NewsletterEmailService:
157
159
  newsletter=newsletter,
158
160
  campaign=campaign
159
161
  )
160
-
162
+
161
163
  # Add newsletter-specific context to the result
162
164
  result.update({
163
165
  'newsletter_id': newsletter.id,
164
166
  'newsletter_title': newsletter.title
165
167
  })
166
-
168
+
167
169
  logger.info(f"Newsletter '{newsletter.title}' sent to {len(emails)} recipients, {result['sent_count']} successful")
168
-
170
+
169
171
  return result
170
-
172
+
171
173
  except Exception as e:
172
174
  logger.error(f"Failed to send newsletter emails: {e}")
173
175
  return {
@@ -176,7 +178,7 @@ class NewsletterEmailService:
176
178
  'sent_count': 0,
177
179
  'failed_count': 0
178
180
  }
179
-
181
+
180
182
  def send_subscription_welcome_email(self, subscription: NewsletterSubscription) -> bool:
181
183
  """
182
184
  Send welcome email to new newsletter subscriber.
@@ -190,7 +192,7 @@ class NewsletterEmailService:
190
192
  try:
191
193
  context = {
192
194
  'email_title': f"Welcome to {subscription.newsletter.title}",
193
- 'greeting': f"Hello",
195
+ 'greeting': "Hello",
194
196
  'main_text': f"Thank you for subscribing to our newsletter <strong>{subscription.newsletter.title}</strong>!",
195
197
  'main_html_content': f"""
196
198
  <p>You'll receive updates and news directly to your inbox at <strong>{subscription.email}</strong>.</p>
@@ -199,7 +201,7 @@ class NewsletterEmailService:
199
201
  """,
200
202
  'secondary_text': f'If you no longer wish to receive these emails, you can <a href="/mailer/unsubscribe/{subscription.id}/">unsubscribe here</a>.'
201
203
  }
202
-
204
+
203
205
  self.email_service.send_template(
204
206
  subject=f"Welcome to {subscription.newsletter.title}",
205
207
  template_name="emails/base_email",
@@ -207,14 +209,14 @@ class NewsletterEmailService:
207
209
  recipient_list=[subscription.email],
208
210
  fail_silently=False
209
211
  )
210
-
212
+
211
213
  logger.info(f"Welcome email sent to {subscription.email}")
212
214
  return True
213
-
215
+
214
216
  except Exception as e:
215
217
  logger.error(f"Failed to send welcome email to {subscription.email}: {e}")
216
218
  return False
217
-
219
+
218
220
  def send_unsubscribe_confirmation_email(self, subscription: NewsletterSubscription) -> bool:
219
221
  """
220
222
  Send unsubscribe confirmation email.
@@ -228,7 +230,7 @@ class NewsletterEmailService:
228
230
  try:
229
231
  context = {
230
232
  'email_title': "Unsubscribe Confirmation",
231
- 'greeting': f"Hello",
233
+ 'greeting': "Hello",
232
234
  'main_text': f"You have been successfully unsubscribed from <strong>{subscription.newsletter.title}</strong>.",
233
235
  'main_html_content': f"""
234
236
  <p>Your email address <strong>{subscription.email}</strong> will no longer receive emails from this newsletter.</p>
@@ -236,7 +238,7 @@ class NewsletterEmailService:
236
238
  <p>We're sorry to see you go!</p>
237
239
  """
238
240
  }
239
-
241
+
240
242
  self.email_service.send_template(
241
243
  subject=f"Unsubscribed from {subscription.newsletter.title}",
242
244
  template_name="emails/base_email",
@@ -244,14 +246,14 @@ class NewsletterEmailService:
244
246
  recipient_list=[subscription.email],
245
247
  fail_silently=False
246
248
  )
247
-
249
+
248
250
  logger.info(f"Unsubscribe confirmation sent to {subscription.email}")
249
251
  return True
250
-
252
+
251
253
  except Exception as e:
252
254
  logger.error(f"Failed to send unsubscribe confirmation to {subscription.email}: {e}")
253
255
  return False
254
-
256
+
255
257
  def send_bulk_email(
256
258
  self,
257
259
  recipients: List[str],
@@ -289,7 +291,7 @@ class NewsletterEmailService:
289
291
  """
290
292
  sent_count = 0
291
293
  failed_count = 0
292
-
294
+
293
295
  try:
294
296
  for recipient in recipients:
295
297
  try:
@@ -303,7 +305,7 @@ class NewsletterEmailService:
303
305
  newsletter=newsletter,
304
306
  campaign=campaign
305
307
  )
306
-
308
+
307
309
  context = {
308
310
  'email_title': email_title,
309
311
  'greeting': "Hello",
@@ -313,7 +315,7 @@ class NewsletterEmailService:
313
315
  'button_url': button_url,
314
316
  'secondary_text': secondary_text
315
317
  }
316
-
318
+
317
319
  # Send email with tracking if enabled
318
320
  if enable_tracking and email_log:
319
321
  success = self.email_service.send_template_with_tracking(
@@ -344,7 +346,7 @@ class NewsletterEmailService:
344
346
  recipient_list=[recipient],
345
347
  fail_silently=False
346
348
  ) > 0
347
-
349
+
348
350
  # Update email log status
349
351
  if enable_tracking and email_log:
350
352
  if success:
@@ -360,26 +362,26 @@ class NewsletterEmailService:
360
362
  sent_count += 1
361
363
  else:
362
364
  failed_count += 1
363
-
365
+
364
366
  except Exception as e:
365
367
  logger.error(f"Failed to send email to {recipient}: {e}")
366
368
  failed_count += 1
367
-
369
+
368
370
  # Update email log if exists
369
371
  if enable_tracking and email_log:
370
372
  email_log.status = EmailLog.EmailLogStatus.FAILED
371
373
  email_log.error_message = str(e)
372
374
  email_log.save()
373
-
375
+
374
376
  logger.info(f"Bulk email sent to {len(recipients)} recipients, {sent_count} successful")
375
-
377
+
376
378
  return {
377
379
  'success': sent_count > 0,
378
380
  'sent_count': sent_count,
379
381
  'failed_count': failed_count,
380
382
  'total_recipients': len(recipients)
381
383
  }
382
-
384
+
383
385
  except Exception as e:
384
386
  logger.error(f"Failed to send bulk emails: {e}")
385
387
  return {
@@ -5,9 +5,10 @@ Handles automatic email notifications and newsletter management.
5
5
  """
6
6
 
7
7
  import logging
8
+
9
+ from django.contrib.auth import get_user_model
8
10
  from django.db.models.signals import post_save, pre_delete
9
11
  from django.dispatch import receiver
10
- from django.contrib.auth import get_user_model
11
12
 
12
13
  from .models import Newsletter, NewsletterSubscription
13
14
 
@@ -59,7 +60,7 @@ def auto_subscribe_new_users(sender, instance, created, **kwargs):
59
60
  try:
60
61
  # Find newsletters with auto_subscribe enabled
61
62
  auto_newsletters = Newsletter.objects.filter(auto_subscribe=True, is_active=True)
62
-
63
+
63
64
  for newsletter in auto_newsletters:
64
65
  NewsletterSubscription.objects.get_or_create(
65
66
  newsletter=newsletter,
@@ -70,6 +71,6 @@ def auto_subscribe_new_users(sender, instance, created, **kwargs):
70
71
  }
71
72
  )
72
73
  logger.info(f"Auto-subscribed {instance.email} to {newsletter.title}")
73
-
74
+
74
75
  except Exception as e:
75
76
  logger.error(f"Failed to auto-subscribe user {instance.email}: {e}")
@@ -2,8 +2,8 @@
2
2
  DRF URLs for newsletter application.
3
3
  """
4
4
 
5
- from django.urls import path, include
6
- from rest_framework.routers import DefaultRouter
5
+ from django.urls import include, path
6
+
7
7
  from . import views
8
8
 
9
9
  app_name = 'cfg_newsletter'
@@ -13,28 +13,28 @@ api_urlpatterns = [
13
13
  # Newsletters
14
14
  path('newsletters/', views.NewsletterListView.as_view(), name='newsletter-list'),
15
15
  path('newsletters/<int:pk>/', views.NewsletterDetailView.as_view(), name='newsletter-detail'),
16
-
16
+
17
17
  # Subscriptions
18
18
  path('subscribe/', views.SubscribeView.as_view(), name='subscribe'),
19
19
  path('unsubscribe/', views.UnsubscribeView.as_view(), name='unsubscribe'),
20
20
  path('subscriptions/', views.SubscriptionListView.as_view(), name='subscription-list'),
21
-
21
+
22
22
  # Campaigns
23
23
  path('campaigns/', views.NewsletterCampaignListView.as_view(), name='campaign-list'),
24
24
  path('campaigns/<int:pk>/', views.NewsletterCampaignDetailView.as_view(), name='campaign-detail'),
25
25
  path('campaigns/send/', views.SendCampaignView.as_view(), name='send-campaign'),
26
-
26
+
27
27
  # Email operations
28
28
  path('test/', views.TestEmailView.as_view(), name='test-email'),
29
29
  path('bulk/', views.BulkEmailView.as_view(), name='bulk-email'),
30
-
30
+
31
31
  # Logs
32
32
  path('logs/', views.EmailLogListView.as_view(), name='email-logs'),
33
33
  ]
34
34
 
35
35
  urlpatterns = [
36
36
  path('', include(api_urlpatterns)),
37
-
37
+
38
38
  # Tracking endpoints (no auth required) - accept any string to handle invalid UUIDs gracefully
39
39
  path('track/open/<str:email_log_id>/', views.TrackEmailOpenView.as_view(), name='track-open'),
40
40
  path('track/click/<str:email_log_id>/', views.TrackEmailClickView.as_view(), name='track-click'),
@@ -3,44 +3,39 @@ Newsletter views package.
3
3
  """
4
4
 
5
5
  # Newsletter views
6
- from .newsletters import NewsletterListView, NewsletterDetailView
7
-
8
- # Subscription views
9
- from .subscriptions import SubscribeView, UnsubscribeView, SubscriptionListView
10
-
11
6
  # Campaign views
12
- from .campaigns import (
13
- NewsletterCampaignListView,
14
- NewsletterCampaignDetailView,
15
- SendCampaignView
16
- )
7
+ from .campaigns import NewsletterCampaignDetailView, NewsletterCampaignListView, SendCampaignView
17
8
 
18
9
  # Email views
19
- from .emails import TestEmailView, BulkEmailView, EmailLogListView
10
+ from .emails import BulkEmailView, EmailLogListView, TestEmailView
11
+ from .newsletters import NewsletterDetailView, NewsletterListView
12
+
13
+ # Subscription views
14
+ from .subscriptions import SubscribeView, SubscriptionListView, UnsubscribeView
20
15
 
21
16
  # Tracking views
22
- from .tracking import TrackEmailOpenView, TrackEmailClickView
17
+ from .tracking import TrackEmailClickView, TrackEmailOpenView
23
18
 
24
19
  __all__ = [
25
20
  # Newsletters
26
21
  'NewsletterListView',
27
22
  'NewsletterDetailView',
28
-
23
+
29
24
  # Subscriptions
30
- 'SubscribeView',
25
+ 'SubscribeView',
31
26
  'UnsubscribeView',
32
27
  'SubscriptionListView',
33
-
28
+
34
29
  # Campaigns
35
30
  'NewsletterCampaignListView',
36
- 'NewsletterCampaignDetailView',
31
+ 'NewsletterCampaignDetailView',
37
32
  'SendCampaignView',
38
-
33
+
39
34
  # Emails
40
35
  'TestEmailView',
41
- 'BulkEmailView',
36
+ 'BulkEmailView',
42
37
  'EmailLogListView',
43
-
38
+
44
39
  # Tracking
45
40
  'TrackEmailOpenView',
46
41
  'TrackEmailClickView',
@@ -2,27 +2,27 @@
2
2
  Campaign views.
3
3
  """
4
4
 
5
+ from drf_spectacular.utils import extend_schema
5
6
  from rest_framework import generics, status
6
- from rest_framework.response import Response
7
7
  from rest_framework.permissions import IsAuthenticated
8
- from drf_spectacular.utils import extend_schema
8
+ from rest_framework.response import Response
9
9
 
10
10
  from ..models import NewsletterCampaign
11
11
  from ..serializers import (
12
+ ErrorResponseSerializer,
12
13
  NewsletterCampaignSerializer,
13
- SendCampaignSerializer,
14
14
  SendCampaignResponseSerializer,
15
- ErrorResponseSerializer,
15
+ SendCampaignSerializer,
16
16
  )
17
17
 
18
18
 
19
19
  class NewsletterCampaignListView(generics.ListCreateAPIView):
20
20
  """List and create newsletter campaigns."""
21
-
21
+
22
22
  queryset = NewsletterCampaign.objects.all()
23
23
  serializer_class = NewsletterCampaignSerializer
24
24
  permission_classes = [IsAuthenticated]
25
-
25
+
26
26
  @extend_schema(
27
27
  summary="List Newsletter Campaigns",
28
28
  description="Get a list of all newsletter campaigns.",
@@ -31,7 +31,7 @@ class NewsletterCampaignListView(generics.ListCreateAPIView):
31
31
  )
32
32
  def get(self, request, *args, **kwargs):
33
33
  return super().get(request, *args, **kwargs)
34
-
34
+
35
35
  @extend_schema(
36
36
  summary="Create Newsletter Campaign",
37
37
  description="Create a new newsletter campaign.",
@@ -45,11 +45,11 @@ class NewsletterCampaignListView(generics.ListCreateAPIView):
45
45
 
46
46
  class NewsletterCampaignDetailView(generics.RetrieveUpdateDestroyAPIView):
47
47
  """Retrieve, update, or delete a newsletter campaign."""
48
-
48
+
49
49
  queryset = NewsletterCampaign.objects.all()
50
50
  serializer_class = NewsletterCampaignSerializer
51
51
  permission_classes = [IsAuthenticated]
52
-
52
+
53
53
  @extend_schema(
54
54
  summary="Get Campaign Details",
55
55
  description="Retrieve details of a specific newsletter campaign.",
@@ -58,7 +58,7 @@ class NewsletterCampaignDetailView(generics.RetrieveUpdateDestroyAPIView):
58
58
  )
59
59
  def get(self, request, *args, **kwargs):
60
60
  return super().get(request, *args, **kwargs)
61
-
61
+
62
62
  @extend_schema(
63
63
  summary="Update Campaign",
64
64
  description="Update a newsletter campaign.",
@@ -68,7 +68,7 @@ class NewsletterCampaignDetailView(generics.RetrieveUpdateDestroyAPIView):
68
68
  )
69
69
  def put(self, request, *args, **kwargs):
70
70
  return super().put(request, *args, **kwargs)
71
-
71
+
72
72
  @extend_schema(
73
73
  summary="Delete Campaign",
74
74
  description="Delete a newsletter campaign.",
@@ -81,10 +81,10 @@ class NewsletterCampaignDetailView(generics.RetrieveUpdateDestroyAPIView):
81
81
 
82
82
  class SendCampaignView(generics.CreateAPIView):
83
83
  """Send a newsletter campaign."""
84
-
84
+
85
85
  serializer_class = SendCampaignSerializer
86
86
  permission_classes = [IsAuthenticated]
87
-
87
+
88
88
  @extend_schema(
89
89
  summary="Send Newsletter Campaign",
90
90
  description="Send a newsletter campaign to all subscribers.",
@@ -99,20 +99,20 @@ class SendCampaignView(generics.CreateAPIView):
99
99
  def post(self, request, *args, **kwargs):
100
100
  serializer = self.get_serializer(data=request.data)
101
101
  serializer.is_valid(raise_exception=True)
102
-
102
+
103
103
  campaign_id = serializer.validated_data['campaign_id']
104
-
104
+
105
105
  try:
106
106
  campaign = NewsletterCampaign.objects.get(id=campaign_id)
107
-
107
+
108
108
  if campaign.status != NewsletterCampaign.CampaignStatus.DRAFT:
109
109
  return Response(
110
110
  {'success': False, 'error': 'Campaign is not in draft status'},
111
111
  status=status.HTTP_400_BAD_REQUEST
112
112
  )
113
-
113
+
114
114
  success = campaign.send_campaign()
115
-
115
+
116
116
  if success:
117
117
  # Get updated campaign data
118
118
  campaign.refresh_from_db()
@@ -130,7 +130,7 @@ class SendCampaignView(generics.CreateAPIView):
130
130
  {'success': False, 'error': 'Failed to send campaign'},
131
131
  status=status.HTTP_400_BAD_REQUEST
132
132
  )
133
-
133
+
134
134
  except NewsletterCampaign.DoesNotExist:
135
135
  return Response(
136
136
  {'success': False, 'error': 'Campaign not found'},