django-cfg 1.3.7__py3-none-any.whl → 1.3.11__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 (246) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/__init__.py +24 -8
  3. django_cfg/apps/accounts/admin/activity_admin.py +146 -0
  4. django_cfg/apps/accounts/admin/filters.py +98 -22
  5. django_cfg/apps/accounts/admin/group_admin.py +86 -0
  6. django_cfg/apps/accounts/admin/inlines.py +42 -13
  7. django_cfg/apps/accounts/admin/otp_admin.py +115 -0
  8. django_cfg/apps/accounts/admin/registration_admin.py +173 -0
  9. django_cfg/apps/accounts/admin/resources.py +123 -19
  10. django_cfg/apps/accounts/admin/twilio_admin.py +327 -0
  11. django_cfg/apps/accounts/admin/user_admin.py +362 -0
  12. django_cfg/apps/agents/admin/__init__.py +17 -4
  13. django_cfg/apps/agents/admin/execution_admin.py +204 -183
  14. django_cfg/apps/agents/admin/registry_admin.py +230 -255
  15. django_cfg/apps/agents/admin/toolsets_admin.py +274 -321
  16. django_cfg/apps/agents/core/__init__.py +1 -1
  17. django_cfg/apps/agents/core/django_agent.py +221 -0
  18. django_cfg/apps/agents/core/exceptions.py +14 -0
  19. django_cfg/apps/agents/core/orchestrator.py +18 -3
  20. django_cfg/apps/knowbase/admin/__init__.py +1 -1
  21. django_cfg/apps/knowbase/admin/archive_admin.py +352 -640
  22. django_cfg/apps/knowbase/admin/chat_admin.py +258 -192
  23. django_cfg/apps/knowbase/admin/document_admin.py +269 -262
  24. django_cfg/apps/knowbase/admin/external_data_admin.py +271 -489
  25. django_cfg/apps/knowbase/config/settings.py +21 -4
  26. django_cfg/apps/knowbase/views/chat_views.py +3 -0
  27. django_cfg/apps/leads/admin/__init__.py +3 -1
  28. django_cfg/apps/leads/admin/leads_admin.py +235 -35
  29. django_cfg/apps/maintenance/admin/__init__.py +2 -2
  30. django_cfg/apps/maintenance/admin/api_key_admin.py +125 -63
  31. django_cfg/apps/maintenance/admin/log_admin.py +143 -61
  32. django_cfg/apps/maintenance/admin/scheduled_admin.py +212 -301
  33. django_cfg/apps/maintenance/admin/site_admin.py +213 -352
  34. django_cfg/apps/newsletter/admin/__init__.py +29 -2
  35. django_cfg/apps/newsletter/admin/newsletter_admin.py +531 -193
  36. django_cfg/apps/payments/admin/__init__.py +18 -27
  37. django_cfg/apps/payments/admin/api_keys_admin.py +179 -546
  38. django_cfg/apps/payments/admin/balance_admin.py +166 -632
  39. django_cfg/apps/payments/admin/currencies_admin.py +235 -607
  40. django_cfg/apps/payments/admin/endpoint_groups_admin.py +127 -0
  41. django_cfg/apps/payments/admin/filters.py +83 -3
  42. django_cfg/apps/payments/admin/networks_admin.py +269 -0
  43. django_cfg/apps/payments/admin/payments_admin.py +183 -460
  44. django_cfg/apps/payments/admin/subscriptions_admin.py +119 -636
  45. django_cfg/apps/payments/admin/tariffs_admin.py +248 -0
  46. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +153 -34
  47. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  48. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  49. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  50. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  51. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  52. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  53. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  54. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +43 -17
  55. django_cfg/apps/payments/admin_interface/views/__init__.py +2 -0
  56. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  57. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +109 -63
  58. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  59. django_cfg/apps/payments/config/__init__.py +14 -15
  60. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  61. django_cfg/apps/payments/config/helpers.py +8 -13
  62. django_cfg/apps/payments/management/commands/manage_currencies.py +236 -274
  63. django_cfg/apps/payments/management/commands/manage_providers.py +4 -1
  64. django_cfg/apps/payments/middleware/api_access.py +32 -6
  65. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  66. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  67. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  68. django_cfg/apps/payments/models/balance.py +12 -0
  69. django_cfg/apps/payments/models/currencies.py +106 -32
  70. django_cfg/apps/payments/models/managers/currency_managers.py +65 -0
  71. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  72. django_cfg/apps/payments/models/payments.py +94 -0
  73. django_cfg/apps/payments/services/core/base.py +4 -4
  74. django_cfg/apps/payments/services/core/currency_service.py +35 -28
  75. django_cfg/apps/payments/services/core/payment_service.py +266 -39
  76. django_cfg/apps/payments/services/providers/__init__.py +3 -0
  77. django_cfg/apps/payments/services/providers/base.py +303 -41
  78. django_cfg/apps/payments/services/providers/models/__init__.py +42 -0
  79. django_cfg/apps/payments/services/providers/models/base.py +145 -0
  80. django_cfg/apps/payments/services/providers/models/providers.py +87 -0
  81. django_cfg/apps/payments/services/providers/models/universal.py +48 -0
  82. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +31 -0
  83. django_cfg/apps/payments/services/providers/nowpayments/config.py +70 -0
  84. django_cfg/apps/payments/services/providers/nowpayments/models.py +150 -0
  85. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +879 -0
  86. django_cfg/apps/payments/services/providers/nowpayments/provider.py +557 -0
  87. django_cfg/apps/payments/services/providers/nowpayments/sync.py +196 -0
  88. django_cfg/apps/payments/services/providers/registry.py +9 -37
  89. django_cfg/apps/payments/services/providers/sync_service.py +277 -0
  90. django_cfg/apps/payments/services/types/requests.py +19 -7
  91. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  92. django_cfg/apps/payments/static/payments/js/api-client.js +29 -6
  93. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  94. django_cfg/apps/payments/static/payments/js/payment-form.js +98 -32
  95. django_cfg/apps/payments/tasks/__init__.py +39 -0
  96. django_cfg/apps/payments/tasks/types.py +73 -0
  97. django_cfg/apps/payments/tasks/usage_tracking.py +308 -0
  98. django_cfg/apps/payments/templates/admin/payments/_components/dashboard_header.html +23 -0
  99. django_cfg/apps/payments/templates/admin/payments/_components/stats_card.html +25 -0
  100. django_cfg/apps/payments/templates/admin/payments/_components/stats_grid.html +16 -0
  101. django_cfg/apps/payments/templates/admin/payments/apikey/change_list.html +39 -0
  102. django_cfg/apps/payments/templates/admin/payments/balance/change_list.html +50 -0
  103. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +40 -0
  104. django_cfg/apps/payments/templates/admin/payments/payment/change_list.html +48 -0
  105. django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html +48 -0
  106. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  107. django_cfg/apps/payments/urls.py +3 -2
  108. django_cfg/apps/payments/urls_admin.py +1 -1
  109. django_cfg/apps/payments/views/api/currencies.py +8 -5
  110. django_cfg/apps/payments/views/overview/services.py +2 -2
  111. django_cfg/apps/payments/views/serializers/currencies.py +22 -8
  112. django_cfg/apps/support/admin/__init__.py +10 -1
  113. django_cfg/apps/support/admin/support_admin.py +338 -141
  114. django_cfg/apps/tasks/admin/__init__.py +11 -0
  115. django_cfg/apps/tasks/admin/tasks_admin.py +430 -0
  116. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  117. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  118. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  119. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  120. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  121. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  122. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  123. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  124. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  125. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  126. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  127. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  128. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  129. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  130. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  131. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  132. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  133. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  134. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  135. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  136. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  137. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  138. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  139. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  140. django_cfg/apps/tasks/urls.py +2 -2
  141. django_cfg/apps/tasks/urls_admin.py +2 -2
  142. django_cfg/apps/tasks/utils/__init__.py +1 -0
  143. django_cfg/apps/tasks/utils/simulator.py +356 -0
  144. django_cfg/apps/tasks/views/__init__.py +16 -0
  145. django_cfg/apps/tasks/views/api.py +569 -0
  146. django_cfg/apps/tasks/views/dashboard.py +58 -0
  147. django_cfg/config.py +1 -1
  148. django_cfg/core/config.py +10 -5
  149. django_cfg/core/generation.py +1 -1
  150. django_cfg/core/integration/__init__.py +21 -0
  151. django_cfg/management/commands/__init__.py +13 -1
  152. django_cfg/management/commands/migrate_all.py +9 -3
  153. django_cfg/management/commands/migrator.py +11 -6
  154. django_cfg/management/commands/rundramatiq.py +3 -2
  155. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  156. django_cfg/middleware/__init__.py +0 -2
  157. django_cfg/models/api_keys.py +115 -0
  158. django_cfg/models/constance.py +0 -11
  159. django_cfg/models/payments.py +137 -3
  160. django_cfg/modules/django_admin/__init__.py +64 -0
  161. django_cfg/modules/django_admin/decorators/__init__.py +13 -0
  162. django_cfg/modules/django_admin/decorators/actions.py +106 -0
  163. django_cfg/modules/django_admin/decorators/display.py +106 -0
  164. django_cfg/modules/django_admin/mixins/__init__.py +14 -0
  165. django_cfg/modules/django_admin/mixins/display_mixin.py +81 -0
  166. django_cfg/modules/django_admin/mixins/optimization_mixin.py +41 -0
  167. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +202 -0
  168. django_cfg/modules/django_admin/models/__init__.py +20 -0
  169. django_cfg/modules/django_admin/models/action_models.py +33 -0
  170. django_cfg/modules/django_admin/models/badge_models.py +20 -0
  171. django_cfg/modules/django_admin/models/base.py +26 -0
  172. django_cfg/modules/django_admin/models/display_models.py +31 -0
  173. django_cfg/modules/django_admin/utils/badges.py +159 -0
  174. django_cfg/modules/django_admin/utils/displays.py +247 -0
  175. django_cfg/modules/django_currency/__init__.py +2 -2
  176. django_cfg/modules/django_currency/clients/__init__.py +2 -2
  177. django_cfg/modules/django_currency/clients/hybrid_client.py +587 -0
  178. django_cfg/modules/django_currency/core/converter.py +12 -12
  179. django_cfg/modules/django_currency/database/__init__.py +2 -2
  180. django_cfg/modules/django_currency/database/database_loader.py +93 -42
  181. django_cfg/modules/django_llm/llm/client.py +10 -2
  182. django_cfg/modules/django_tasks.py +54 -21
  183. django_cfg/modules/django_unfold/callbacks/actions.py +1 -1
  184. django_cfg/modules/django_unfold/callbacks/statistics.py +1 -1
  185. django_cfg/modules/django_unfold/dashboard.py +14 -13
  186. django_cfg/modules/django_unfold/models/config.py +1 -1
  187. django_cfg/registry/core.py +7 -9
  188. django_cfg/registry/third_party.py +2 -2
  189. django_cfg/template_archive/django_sample.zip +0 -0
  190. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/METADATA +2 -1
  191. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/RECORD +198 -160
  192. django_cfg/apps/accounts/admin/activity.py +0 -96
  193. django_cfg/apps/accounts/admin/group.py +0 -17
  194. django_cfg/apps/accounts/admin/otp.py +0 -59
  195. django_cfg/apps/accounts/admin/registration_source.py +0 -97
  196. django_cfg/apps/accounts/admin/twilio_response.py +0 -227
  197. django_cfg/apps/accounts/admin/user.py +0 -300
  198. django_cfg/apps/agents/core/agent.py +0 -281
  199. django_cfg/apps/payments/admin_interface/old/payments/base.html +0 -175
  200. django_cfg/apps/payments/admin_interface/old/payments/components/dev_tool_card.html +0 -125
  201. django_cfg/apps/payments/admin_interface/old/payments/components/loading_spinner.html +0 -16
  202. django_cfg/apps/payments/admin_interface/old/payments/components/ngrok_status_card.html +0 -113
  203. django_cfg/apps/payments/admin_interface/old/payments/components/notification.html +0 -27
  204. django_cfg/apps/payments/admin_interface/old/payments/components/provider_card.html +0 -86
  205. django_cfg/apps/payments/admin_interface/old/payments/components/status_card.html +0 -35
  206. django_cfg/apps/payments/admin_interface/old/payments/currency_converter.html +0 -382
  207. django_cfg/apps/payments/admin_interface/old/payments/payment_dashboard.html +0 -309
  208. django_cfg/apps/payments/admin_interface/old/payments/payment_form.html +0 -303
  209. django_cfg/apps/payments/admin_interface/old/payments/payment_list.html +0 -382
  210. django_cfg/apps/payments/admin_interface/old/payments/payment_status.html +0 -500
  211. django_cfg/apps/payments/admin_interface/old/payments/webhook_dashboard.html +0 -518
  212. django_cfg/apps/payments/admin_interface/old/static/payments/css/components.css +0 -619
  213. django_cfg/apps/payments/admin_interface/old/static/payments/css/dashboard.css +0 -188
  214. django_cfg/apps/payments/admin_interface/old/static/payments/js/components.js +0 -545
  215. django_cfg/apps/payments/admin_interface/old/static/payments/js/ngrok-status.js +0 -163
  216. django_cfg/apps/payments/admin_interface/old/static/payments/js/utils.js +0 -412
  217. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  218. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  219. django_cfg/apps/payments/config/constance/fields.py +0 -69
  220. django_cfg/apps/payments/config/constance/settings.py +0 -160
  221. django_cfg/apps/payments/services/providers/nowpayments.py +0 -478
  222. django_cfg/apps/tasks/admin.py +0 -320
  223. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  224. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  225. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  226. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  227. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  228. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  229. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  230. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  231. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  232. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  233. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  234. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  235. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  236. django_cfg/apps/tasks/views.py +0 -461
  237. django_cfg/management/commands/auto_generate.py +0 -486
  238. django_cfg/middleware/static_nocache.py +0 -55
  239. django_cfg/modules/django_currency/clients/yahoo_client.py +0 -157
  240. /django_cfg/modules/{django_unfold → django_admin}/icons/README.md +0 -0
  241. /django_cfg/modules/{django_unfold → django_admin}/icons/__init__.py +0 -0
  242. /django_cfg/modules/{django_unfold → django_admin}/icons/constants.py +0 -0
  243. /django_cfg/modules/{django_unfold → django_admin}/icons/generate_icons.py +0 -0
  244. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/WHEEL +0 -0
  245. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
  246. {django_cfg-1.3.7.dist-info → django_cfg-1.3.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,320 +0,0 @@
1
- """
2
- Admin interface for Dramatiq task management.
3
-
4
- Provides web interface for starting workers, checking queue status,
5
- and clearing queues with AJAX endpoints and interactive buttons.
6
- """
7
-
8
- import logging
9
- import subprocess
10
- import sys
11
- from typing import Dict, Any
12
-
13
- from django.db.models import Count
14
- from django.contrib import admin
15
- from django.contrib.admin.views.main import ChangeList
16
- from django.http import JsonResponse
17
- from django.urls import path
18
- from django.views.decorators.csrf import csrf_exempt
19
- from unfold.admin import ModelAdmin
20
-
21
- try:
22
- from django_dramatiq.models import Task
23
- from django_dramatiq.admin import TaskAdmin as BaseDramatiqTaskAdmin
24
- except ImportError:
25
- Task = None
26
- BaseDramatiqTaskAdmin = None
27
-
28
- from ...modules.django_tasks import DjangoTasks
29
-
30
-
31
- class TaskQueueChangeList(ChangeList):
32
- """Custom changelist for task queue management."""
33
-
34
- def __init__(self, *args, **kwargs):
35
- super().__init__(*args, **kwargs)
36
- self.tasks_service = DjangoTasks()
37
-
38
-
39
- class TaskQueueAdmin(ModelAdmin):
40
- """
41
- Enhanced admin for Dramatiq task management.
42
-
43
- Provides buttons for:
44
- - Starting/stopping workers
45
- - Checking queue status
46
- - Clearing queues
47
- - Viewing task statistics
48
- """
49
-
50
- def __init__(self, *args, **kwargs):
51
- super().__init__(*args, **kwargs)
52
- self.logger = logging.getLogger(__name__)
53
- self.tasks_service = DjangoTasks()
54
-
55
- def get_urls(self):
56
- """Add custom URLs for task management."""
57
- urls = super().get_urls()
58
- custom_urls = [
59
- path('queue-status/', csrf_exempt(self.queue_status_view), name='dramatiq_queue_status'),
60
- path('start-workers/', csrf_exempt(self.start_workers_view), name='dramatiq_start_workers'),
61
- path('clear-queues/', csrf_exempt(self.clear_queues_view), name='dramatiq_clear_queues'),
62
- path('task-stats/', csrf_exempt(self.task_stats_view), name='dramatiq_task_stats'),
63
- ]
64
- return custom_urls + urls
65
-
66
- def queue_status_view(self, request):
67
- """Get queue status and statistics."""
68
- if request.method != 'GET':
69
- return JsonResponse({'success': False, 'error': 'Method not allowed'}, status=405)
70
-
71
- try:
72
- # Get queue status using tasks service
73
- status_data = self._get_queue_status()
74
-
75
- return JsonResponse({
76
- 'success': True,
77
- 'data': status_data
78
- })
79
-
80
- except Exception as e:
81
- self.logger.error(f"Queue status check failed: {e}")
82
- return JsonResponse({
83
- 'success': False,
84
- 'error': str(e)
85
- }, status=500)
86
-
87
- def start_workers_view(self, request):
88
- """Start Dramatiq workers."""
89
- if request.method != 'POST':
90
- return JsonResponse({'success': False, 'error': 'Method not allowed'}, status=405)
91
-
92
- try:
93
- # Get parameters from request
94
- processes = int(request.POST.get('processes', 2))
95
- threads = int(request.POST.get('threads', 8))
96
- queues = request.POST.get('queues', '')
97
-
98
- # Validate parameters
99
- if processes < 1 or processes > 16:
100
- return JsonResponse({
101
- 'success': False,
102
- 'error': 'Processes must be between 1 and 16'
103
- }, status=400)
104
-
105
- if threads < 1 or threads > 32:
106
- return JsonResponse({
107
- 'success': False,
108
- 'error': 'Threads must be between 1 and 32'
109
- }, status=400)
110
-
111
- # Build command
112
- cmd = [sys.executable, 'manage.py', 'rundramatiq']
113
- cmd.extend(['--processes', str(processes)])
114
- cmd.extend(['--threads', str(threads)])
115
-
116
- if queues:
117
- cmd.extend(['--queues', queues])
118
-
119
- # Start workers in background
120
- process = subprocess.Popen(
121
- cmd,
122
- stdout=subprocess.PIPE,
123
- stderr=subprocess.PIPE,
124
- cwd=None # Use current working directory
125
- )
126
-
127
- return JsonResponse({
128
- 'success': True,
129
- 'message': f'Started {processes} worker processes with {threads} threads each',
130
- 'pid': process.pid,
131
- 'command': ' '.join(cmd)
132
- })
133
-
134
- except Exception as e:
135
- self.logger.error(f"Start workers failed: {e}")
136
- return JsonResponse({
137
- 'success': False,
138
- 'error': str(e)
139
- }, status=500)
140
-
141
- def clear_queues_view(self, request):
142
- """Clear Dramatiq queues."""
143
- if request.method != 'POST':
144
- return JsonResponse({'success': False, 'error': 'Method not allowed'}, status=405)
145
-
146
- try:
147
- # Get parameters
148
- queue_name = request.POST.get('queue', '')
149
- failed_only = request.POST.get('failed_only', 'false').lower() == 'true'
150
-
151
- # Build command
152
- cmd = [sys.executable, 'manage.py', 'task_clear', '--confirm']
153
-
154
- if queue_name:
155
- cmd.extend(['--queue', queue_name])
156
-
157
- if failed_only:
158
- cmd.append('--failed-only')
159
-
160
- # Execute command
161
- result = subprocess.run(
162
- cmd,
163
- capture_output=True,
164
- text=True,
165
- timeout=30
166
- )
167
-
168
- if result.returncode == 0:
169
- return JsonResponse({
170
- 'success': True,
171
- 'message': 'Queues cleared successfully',
172
- 'output': result.stdout
173
- })
174
- else:
175
- return JsonResponse({
176
- 'success': False,
177
- 'error': result.stderr or 'Clear command failed'
178
- }, status=500)
179
-
180
- except subprocess.TimeoutExpired:
181
- return JsonResponse({
182
- 'success': False,
183
- 'error': 'Clear operation timed out'
184
- }, status=500)
185
- except Exception as e:
186
- self.logger.error(f"Clear queues failed: {e}")
187
- return JsonResponse({
188
- 'success': False,
189
- 'error': str(e)
190
- }, status=500)
191
-
192
- def task_stats_view(self, request):
193
- """Get task statistics."""
194
- if request.method != 'GET':
195
- return JsonResponse({'success': False, 'error': 'Method not allowed'}, status=405)
196
-
197
- try:
198
- # Get task statistics using tasks service
199
- stats_data = self._get_task_statistics()
200
-
201
- return JsonResponse({
202
- 'success': True,
203
- 'data': stats_data
204
- })
205
-
206
- except Exception as e:
207
- self.logger.error(f"Task stats failed: {e}")
208
- return JsonResponse({
209
- 'success': False,
210
- 'error': str(e)
211
- }, status=500)
212
-
213
- def _get_queue_status(self) -> Dict[str, Any]:
214
- """Get current queue status."""
215
- try:
216
- # Use tasks service to get Redis connection
217
- redis_client = self.tasks_service.get_redis_client()
218
-
219
- if not redis_client:
220
- return {
221
- 'error': 'Redis connection not available',
222
- 'queues': {},
223
- 'workers': 0
224
- }
225
-
226
- # Get queue information
227
- queues_info = {}
228
- config = self.tasks_service.config
229
-
230
- if config and config.dramatiq and config.dramatiq.queues:
231
- for queue_name in config.dramatiq.queues:
232
- queue_key = f"dramatiq:default.DQ.{queue_name}"
233
- queue_length = redis_client.llen(queue_key)
234
-
235
- # Get failed queue length
236
- failed_key = f"dramatiq:default.DQ.{queue_name}.failed"
237
- failed_length = redis_client.llen(failed_key)
238
-
239
- queues_info[queue_name] = {
240
- 'pending': queue_length,
241
- 'failed': failed_length,
242
- 'total': queue_length + failed_length
243
- }
244
-
245
- # Get worker information (simplified)
246
- worker_keys = redis_client.keys("dramatiq:worker:*")
247
- active_workers = len(worker_keys) if worker_keys else 0
248
-
249
- return {
250
- 'queues': queues_info,
251
- 'workers': active_workers,
252
- 'redis_connected': True,
253
- 'timestamp': self.tasks_service._get_current_timestamp()
254
- }
255
-
256
- except Exception as e:
257
- self.logger.error(f"Queue status error: {e}")
258
- return {
259
- 'error': str(e),
260
- 'queues': {},
261
- 'workers': 0,
262
- 'redis_connected': False
263
- }
264
-
265
- def _get_task_statistics(self) -> Dict[str, Any]:
266
- """Get task execution statistics."""
267
- try:
268
- if not Task:
269
- return {'error': 'django_dramatiq not available'}
270
-
271
-
272
- stats = Task.tasks.aggregate(
273
- total=Count('id'),
274
- # Add more aggregations as needed
275
- )
276
-
277
- # Get recent tasks
278
- recent_tasks = list(
279
- Task.tasks.order_by('-created_at')[:10]
280
- .values('actor_name', 'status', 'created_at', 'updated_at')
281
- )
282
-
283
- return {
284
- 'statistics': stats,
285
- 'recent_tasks': recent_tasks,
286
- 'timestamp': self.tasks_service._get_current_timestamp()
287
- }
288
-
289
- except Exception as e:
290
- self.logger.error(f"Task statistics error: {e}")
291
- return {'error': str(e)}
292
-
293
-
294
- # Register the enhanced admin if django_dramatiq is available
295
- if Task and BaseDramatiqTaskAdmin:
296
- # Unregister the default admin
297
- admin.site.unregister(Task)
298
-
299
- # Register our enhanced admin
300
- @admin.register(Task)
301
- class EnhancedTaskAdmin(TaskQueueAdmin, BaseDramatiqTaskAdmin):
302
- """Enhanced Task admin with queue management buttons."""
303
-
304
- def get_changelist(self, request, **kwargs):
305
- """Use custom changelist."""
306
- return TaskQueueChangeList
307
-
308
- def changelist_view(self, request, extra_context=None):
309
- """Add extra context for queue management."""
310
- extra_context = extra_context or {}
311
-
312
- # Add queue status to context
313
- try:
314
- queue_status = self._get_queue_status()
315
- extra_context['queue_status'] = queue_status
316
- except Exception as e:
317
- self.logger.error(f"Failed to get queue status: {e}")
318
- extra_context['queue_status'] = {'error': str(e)}
319
-
320
- return super().changelist_view(request, extra_context)