django-cfg 1.4.9__py3-none-any.whl → 1.4.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 (193) hide show
  1. django_cfg/apps/agents/management/commands/create_agent.py +1 -1
  2. django_cfg/apps/agents/management/commands/orchestrator_status.py +3 -3
  3. django_cfg/apps/newsletter/serializers.py +40 -3
  4. django_cfg/apps/newsletter/views/campaigns.py +12 -3
  5. django_cfg/apps/newsletter/views/emails.py +14 -3
  6. django_cfg/apps/newsletter/views/subscriptions.py +12 -2
  7. django_cfg/apps/payments/middleware/api_access.py +6 -2
  8. django_cfg/apps/payments/middleware/rate_limiting.py +2 -1
  9. django_cfg/apps/payments/middleware/usage_tracking.py +5 -1
  10. django_cfg/apps/payments/models/managers/api_key_managers.py +0 -1
  11. django_cfg/apps/payments/models/managers/subscription_managers.py +0 -1
  12. django_cfg/apps/payments/services/core/balance_service.py +5 -5
  13. django_cfg/apps/payments/services/core/subscription_service.py +1 -2
  14. django_cfg/apps/payments/views/api/balances.py +8 -7
  15. django_cfg/apps/payments/views/api/base.py +10 -6
  16. django_cfg/apps/payments/views/api/currencies.py +53 -10
  17. django_cfg/apps/payments/views/api/payments.py +3 -1
  18. django_cfg/apps/payments/views/api/subscriptions.py +2 -5
  19. django_cfg/apps/payments/views/api/webhooks.py +72 -7
  20. django_cfg/apps/payments/views/overview/serializers.py +34 -1
  21. django_cfg/apps/payments/views/overview/views.py +2 -1
  22. django_cfg/apps/payments/views/serializers/payments.py +6 -6
  23. django_cfg/apps/urls.py +106 -45
  24. django_cfg/core/base/config_model.py +2 -2
  25. django_cfg/core/constants.py +1 -1
  26. django_cfg/core/generation/integration_generators/__init__.py +1 -1
  27. django_cfg/core/generation/integration_generators/api.py +82 -41
  28. django_cfg/core/integration/display/startup.py +30 -22
  29. django_cfg/core/integration/url_integration.py +15 -16
  30. django_cfg/dashboard/sections/documentation.py +391 -0
  31. django_cfg/management/commands/check_endpoints.py +11 -160
  32. django_cfg/management/commands/check_settings.py +13 -265
  33. django_cfg/management/commands/clear_constance.py +13 -201
  34. django_cfg/management/commands/create_token.py +13 -321
  35. django_cfg/management/commands/generate_clients.py +23 -0
  36. django_cfg/management/commands/list_urls.py +13 -306
  37. django_cfg/management/commands/migrate_all.py +13 -126
  38. django_cfg/management/commands/migrator.py +13 -396
  39. django_cfg/management/commands/rundramatiq.py +15 -247
  40. django_cfg/management/commands/rundramatiq_simulator.py +12 -429
  41. django_cfg/management/commands/runserver_ngrok.py +15 -160
  42. django_cfg/management/commands/script.py +12 -488
  43. django_cfg/management/commands/show_config.py +12 -215
  44. django_cfg/management/commands/show_urls.py +12 -342
  45. django_cfg/management/commands/superuser.py +15 -295
  46. django_cfg/management/commands/task_clear.py +14 -217
  47. django_cfg/management/commands/task_status.py +13 -248
  48. django_cfg/management/commands/test_email.py +15 -86
  49. django_cfg/management/commands/test_telegram.py +14 -61
  50. django_cfg/management/commands/test_twilio.py +15 -105
  51. django_cfg/management/commands/tree.py +13 -383
  52. django_cfg/management/commands/validate_openapi.py +10 -0
  53. django_cfg/middleware/README.md +1 -1
  54. django_cfg/middleware/user_activity.py +3 -3
  55. django_cfg/models/__init__.py +2 -2
  56. django_cfg/models/api/drf/spectacular.py +6 -6
  57. django_cfg/models/django/__init__.py +2 -2
  58. django_cfg/models/django/openapi.py +238 -0
  59. django_cfg/models/django/{revolution.py → revolution_legacy.py} +8 -0
  60. django_cfg/modules/django_admin/management/__init__.py +0 -0
  61. django_cfg/modules/django_admin/management/commands/__init__.py +0 -0
  62. django_cfg/modules/django_admin/management/commands/check_endpoints.py +169 -0
  63. django_cfg/modules/django_admin/management/commands/check_settings.py +355 -0
  64. django_cfg/modules/django_admin/management/commands/clear_constance.py +208 -0
  65. django_cfg/modules/django_admin/management/commands/create_token.py +328 -0
  66. django_cfg/modules/django_admin/management/commands/list_urls.py +313 -0
  67. django_cfg/modules/django_admin/management/commands/migrate_all.py +133 -0
  68. django_cfg/modules/django_admin/management/commands/migrator.py +403 -0
  69. django_cfg/modules/django_admin/management/commands/script.py +496 -0
  70. django_cfg/modules/django_admin/management/commands/show_config.py +225 -0
  71. django_cfg/modules/django_admin/management/commands/show_urls.py +361 -0
  72. django_cfg/modules/django_admin/management/commands/superuser.py +302 -0
  73. django_cfg/modules/django_admin/management/commands/tree.py +390 -0
  74. django_cfg/modules/django_client/__init__.py +20 -0
  75. django_cfg/modules/django_client/apps.py +35 -0
  76. django_cfg/modules/django_client/core/__init__.py +56 -0
  77. django_cfg/modules/django_client/core/archive/__init__.py +11 -0
  78. django_cfg/modules/django_client/core/archive/manager.py +134 -0
  79. django_cfg/modules/django_client/core/cli/__init__.py +12 -0
  80. django_cfg/modules/django_client/core/cli/main.py +235 -0
  81. django_cfg/modules/django_client/core/config/__init__.py +18 -0
  82. django_cfg/modules/django_client/core/config/config.py +188 -0
  83. django_cfg/modules/django_client/core/config/group.py +101 -0
  84. django_cfg/modules/django_client/core/config/service.py +209 -0
  85. django_cfg/modules/django_client/core/generator/__init__.py +115 -0
  86. django_cfg/modules/django_client/core/generator/base.py +767 -0
  87. django_cfg/modules/django_client/core/generator/python.py +751 -0
  88. django_cfg/modules/django_client/core/generator/templates/python/__init__.py.jinja +9 -0
  89. django_cfg/modules/django_client/core/generator/templates/python/api_wrapper.py.jinja +130 -0
  90. django_cfg/modules/django_client/core/generator/templates/python/app_init.py.jinja +6 -0
  91. django_cfg/modules/django_client/core/generator/templates/python/client/app_client.py.jinja +18 -0
  92. django_cfg/modules/django_client/core/generator/templates/python/client/flat_client.py.jinja +38 -0
  93. django_cfg/modules/django_client/core/generator/templates/python/client/main_client.py.jinja +50 -0
  94. django_cfg/modules/django_client/core/generator/templates/python/client/main_client_file.py.jinja +13 -0
  95. django_cfg/modules/django_client/core/generator/templates/python/client/operation_method.py.jinja +7 -0
  96. django_cfg/modules/django_client/core/generator/templates/python/client/sub_client.py.jinja +11 -0
  97. django_cfg/modules/django_client/core/generator/templates/python/client_file.py.jinja +13 -0
  98. django_cfg/modules/django_client/core/generator/templates/python/main_init.py.jinja +50 -0
  99. django_cfg/modules/django_client/core/generator/templates/python/models/app_models.py.jinja +17 -0
  100. django_cfg/modules/django_client/core/generator/templates/python/models/enum_class.py.jinja +15 -0
  101. django_cfg/modules/django_client/core/generator/templates/python/models/enums.py.jinja +8 -0
  102. django_cfg/modules/django_client/core/generator/templates/python/models/models.py.jinja +17 -0
  103. django_cfg/modules/django_client/core/generator/templates/python/models/schema_class.py.jinja +19 -0
  104. django_cfg/modules/django_client/core/generator/templates/python/utils/logger.py.jinja +255 -0
  105. django_cfg/modules/django_client/core/generator/templates/python/utils/schema.py.jinja +12 -0
  106. django_cfg/modules/django_client/core/generator/templates/typescript/app_index.ts.jinja +2 -0
  107. django_cfg/modules/django_client/core/generator/templates/typescript/client/app_client.ts.jinja +18 -0
  108. django_cfg/modules/django_client/core/generator/templates/typescript/client/client.ts.jinja +327 -0
  109. django_cfg/modules/django_client/core/generator/templates/typescript/client/flat_client.ts.jinja +109 -0
  110. django_cfg/modules/django_client/core/generator/templates/typescript/client/main_client_file.ts.jinja +9 -0
  111. django_cfg/modules/django_client/core/generator/templates/typescript/client/operation.ts.jinja +61 -0
  112. django_cfg/modules/django_client/core/generator/templates/typescript/client/sub_client.ts.jinja +15 -0
  113. django_cfg/modules/django_client/core/generator/templates/typescript/client_file.ts.jinja +9 -0
  114. django_cfg/modules/django_client/core/generator/templates/typescript/index.ts.jinja +5 -0
  115. django_cfg/modules/django_client/core/generator/templates/typescript/main_index.ts.jinja +206 -0
  116. django_cfg/modules/django_client/core/generator/templates/typescript/models/app_models.ts.jinja +8 -0
  117. django_cfg/modules/django_client/core/generator/templates/typescript/models/enums.ts.jinja +4 -0
  118. django_cfg/modules/django_client/core/generator/templates/typescript/models/models.ts.jinja +8 -0
  119. django_cfg/modules/django_client/core/generator/templates/typescript/utils/errors.ts.jinja +114 -0
  120. django_cfg/modules/django_client/core/generator/templates/typescript/utils/http.ts.jinja +98 -0
  121. django_cfg/modules/django_client/core/generator/templates/typescript/utils/logger.ts.jinja +251 -0
  122. django_cfg/modules/django_client/core/generator/templates/typescript/utils/schema.ts.jinja +7 -0
  123. django_cfg/modules/django_client/core/generator/templates/typescript/utils/storage.ts.jinja +114 -0
  124. django_cfg/modules/django_client/core/generator/typescript.py +872 -0
  125. django_cfg/modules/django_client/core/groups/__init__.py +13 -0
  126. django_cfg/modules/django_client/core/groups/detector.py +178 -0
  127. django_cfg/modules/django_client/core/groups/manager.py +314 -0
  128. django_cfg/modules/django_client/core/ir/__init__.py +57 -0
  129. django_cfg/modules/django_client/core/ir/context.py +387 -0
  130. django_cfg/modules/django_client/core/ir/operation.py +518 -0
  131. django_cfg/modules/django_client/core/ir/schema.py +353 -0
  132. django_cfg/modules/django_client/core/parser/__init__.py +74 -0
  133. django_cfg/modules/django_client/core/parser/base.py +648 -0
  134. django_cfg/modules/django_client/core/parser/models/__init__.py +74 -0
  135. django_cfg/modules/django_client/core/parser/models/base.py +212 -0
  136. django_cfg/modules/django_client/core/parser/models/components.py +160 -0
  137. django_cfg/modules/django_client/core/parser/models/openapi.py +203 -0
  138. django_cfg/modules/django_client/core/parser/models/operation.py +207 -0
  139. django_cfg/modules/django_client/core/parser/models/schema.py +266 -0
  140. django_cfg/modules/django_client/core/parser/openapi30.py +56 -0
  141. django_cfg/modules/django_client/core/parser/openapi31.py +64 -0
  142. django_cfg/modules/django_client/core/validation/__init__.py +22 -0
  143. django_cfg/modules/django_client/core/validation/checker.py +134 -0
  144. django_cfg/modules/django_client/core/validation/fixer.py +216 -0
  145. django_cfg/modules/django_client/core/validation/reporter.py +480 -0
  146. django_cfg/modules/django_client/core/validation/rules/__init__.py +11 -0
  147. django_cfg/modules/django_client/core/validation/rules/base.py +96 -0
  148. django_cfg/modules/django_client/core/validation/rules/type_hints.py +288 -0
  149. django_cfg/modules/django_client/core/validation/safety.py +266 -0
  150. django_cfg/modules/django_client/management/__init__.py +3 -0
  151. django_cfg/modules/django_client/management/commands/__init__.py +3 -0
  152. django_cfg/modules/django_client/management/commands/generate_client.py +422 -0
  153. django_cfg/modules/django_client/management/commands/validate_openapi.py +343 -0
  154. django_cfg/modules/django_client/spectacular/__init__.py +9 -0
  155. django_cfg/modules/django_client/spectacular/enum_naming.py +192 -0
  156. django_cfg/modules/django_client/urls.py +72 -0
  157. django_cfg/modules/django_email/management/__init__.py +0 -0
  158. django_cfg/modules/django_email/management/commands/__init__.py +0 -0
  159. django_cfg/modules/django_email/management/commands/test_email.py +93 -0
  160. django_cfg/modules/django_logging/django_logger.py +6 -6
  161. django_cfg/modules/django_ngrok/management/__init__.py +0 -0
  162. django_cfg/modules/django_ngrok/management/commands/__init__.py +0 -0
  163. django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +167 -0
  164. django_cfg/modules/django_tasks/management/__init__.py +0 -0
  165. django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
  166. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +254 -0
  167. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +437 -0
  168. django_cfg/modules/django_tasks/management/commands/task_clear.py +226 -0
  169. django_cfg/modules/django_tasks/management/commands/task_status.py +257 -0
  170. django_cfg/modules/django_telegram/management/__init__.py +0 -0
  171. django_cfg/modules/django_telegram/management/commands/__init__.py +0 -0
  172. django_cfg/modules/django_telegram/management/commands/test_telegram.py +68 -0
  173. django_cfg/modules/django_twilio/management/__init__.py +0 -0
  174. django_cfg/modules/django_twilio/management/commands/__init__.py +0 -0
  175. django_cfg/modules/django_twilio/management/commands/test_twilio.py +112 -0
  176. django_cfg/modules/django_unfold/callbacks/main.py +16 -5
  177. django_cfg/modules/django_unfold/callbacks/revolution.py +41 -36
  178. django_cfg/modules/django_unfold/dashboard.py +1 -1
  179. django_cfg/pyproject.toml +2 -6
  180. django_cfg/registry/third_party.py +5 -7
  181. django_cfg/routing/callbacks.py +1 -1
  182. django_cfg/static/admin/css/prose-unfold.css +666 -0
  183. django_cfg/templates/admin/index.html +8 -0
  184. django_cfg/templates/admin/index_new.html +13 -0
  185. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +15 -3
  186. django_cfg/templates/admin/sections/documentation_section.html +172 -0
  187. django_cfg/templates/admin/snippets/tabs/documentation_tab.html +231 -0
  188. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/METADATA +2 -2
  189. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/RECORD +192 -71
  190. django_cfg/management/commands/generate.py +0 -107
  191. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/WHEEL +0 -0
  192. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/entry_points.txt +0 -0
  193. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,302 +1,22 @@
1
1
  """
2
- Superuser Command for Django Config Toolkit
3
- Enhanced superuser creation with validation and configuration.
4
- """
5
-
6
- import os
7
- import getpass
8
- from pathlib import Path
9
- from django.core.management.base import BaseCommand
10
- from django.core.management import call_command
11
- from django.contrib.auth import get_user_model
12
- from django.core.validators import validate_email
13
- from django.core.exceptions import ValidationError
14
- from django.conf import settings
15
- import questionary
16
- from datetime import datetime
17
- from django_cfg.modules.django_logging import get_logger
18
-
19
- User = get_user_model()
20
-
21
-
22
- logger = get_logger('superuser')
23
-
24
- class Command(BaseCommand):
25
- # Web execution metadata
26
- web_executable = False
27
- requires_input = True
28
- is_destructive = False
29
-
30
- help = 'Create a superuser with enhanced validation and configuration'
2
+ Django-CFG wrapper for superuser command.
31
3
 
32
- def add_arguments(self, parser):
33
- parser.add_argument(
34
- '--username',
35
- type=str,
36
- help='Username for superuser'
37
- )
38
- parser.add_argument(
39
- '--email',
40
- type=str,
41
- help='Email for superuser'
42
- )
43
- parser.add_argument(
44
- '--password',
45
- type=str,
46
- help='Password for superuser'
47
- )
48
- parser.add_argument(
49
- '--first-name',
50
- type=str,
51
- help='First name for superuser'
52
- )
53
- parser.add_argument(
54
- '--last-name',
55
- type=str,
56
- help='Last name for superuser'
57
- )
58
- parser.add_argument(
59
- '--interactive',
60
- action='store_true',
61
- help='Run in interactive mode'
62
- )
4
+ This is a simple alias for django_admin.management.commands.superuser.
5
+ All logic is in django_admin module.
63
6
 
64
- def handle(self, *args, **options):
65
- logger.info("Starting superuser command")
66
- if options['interactive'] or not any([options['username'], options['email'], options['password']]):
67
- self.create_superuser_interactive()
68
- else:
69
- self.create_superuser_non_interactive(options)
70
-
71
- def create_superuser_interactive(self):
72
- """Create superuser interactively"""
73
- self.stdout.write(self.style.SUCCESS('\n👑 Superuser Creation Tool - Django Config Toolkit\n'))
74
-
75
- # Check if superuser already exists
76
- if User.objects.filter(is_superuser=True).exists():
77
- self.stdout.write(self.style.WARNING('⚠️ Superuser already exists'))
78
- overwrite = questionary.confirm('Do you want to create another superuser?').ask()
79
- if not overwrite:
80
- self.stdout.write('Goodbye! 👋')
81
- return
82
-
83
- # Get user details
84
- user_data = self.get_user_details_interactive()
85
-
86
- # Validate data
87
- if not self.validate_user_data(user_data):
88
- return
89
-
90
- # Create superuser
91
- self.create_superuser(user_data)
92
-
93
- def create_superuser_non_interactive(self, options):
94
- """Create superuser non-interactively"""
95
- user_data = {
96
- 'username': options['username'],
97
- 'email': options['email'],
98
- 'password': options['password'],
99
- 'first_name': options['first_name'] or '',
100
- 'last_name': options['last_name'] or '',
101
- }
102
-
103
- # Validate required fields
104
- if not all([user_data['username'], user_data['email'], user_data['password']]):
105
- self.stdout.write(self.style.ERROR('❌ Username, email, and password are required'))
106
- return
107
-
108
- # Validate data
109
- if not self.validate_user_data(user_data):
110
- return
111
-
112
- # Create superuser
113
- self.create_superuser(user_data)
114
-
115
- def get_user_details_interactive(self):
116
- """Get user details interactively"""
117
- user_data = {}
118
-
119
- # Username
120
- while True:
121
- username = questionary.text('Username:').ask()
122
- if not username:
123
- self.stdout.write(self.style.ERROR('❌ Username is required'))
124
- continue
125
-
126
- if User.objects.filter(username=username).exists():
127
- self.stdout.write(self.style.ERROR('❌ Username already exists'))
128
- continue
129
-
130
- user_data['username'] = username
131
- break
132
-
133
- # Email
134
- while True:
135
- email = questionary.text('Email:').ask()
136
- if not email:
137
- self.stdout.write(self.style.ERROR('❌ Email is required'))
138
- continue
139
-
140
- try:
141
- validate_email(email)
142
- except ValidationError:
143
- self.stdout.write(self.style.ERROR('❌ Invalid email format'))
144
- continue
145
-
146
- if User.objects.filter(email=email).exists():
147
- self.stdout.write(self.style.ERROR('❌ Email already exists'))
148
- continue
149
-
150
- user_data['email'] = email
151
- break
152
-
153
- # Password
154
- while True:
155
- password = questionary.password('Password:').ask()
156
- if not password:
157
- self.stdout.write(self.style.ERROR('❌ Password is required'))
158
- continue
159
-
160
- if len(password) < 8:
161
- self.stdout.write(self.style.WARNING('⚠️ Password should be at least 8 characters'))
162
- confirm = questionary.confirm('Continue with weak password?').ask()
163
- if not confirm:
164
- continue
165
-
166
- confirm_password = questionary.password('Confirm password:').ask()
167
- if password != confirm_password:
168
- self.stdout.write(self.style.ERROR('❌ Passwords do not match'))
169
- continue
170
-
171
- user_data['password'] = password
172
- break
173
-
174
- # Optional fields
175
- user_data['first_name'] = questionary.text('First name (optional):').ask() or ''
176
- user_data['last_name'] = questionary.text('Last name (optional):').ask() or ''
177
-
178
- return user_data
179
-
180
- def validate_user_data(self, user_data):
181
- """Validate user data"""
182
- errors = []
183
-
184
- # Check required fields
185
- if not user_data.get('username'):
186
- errors.append('Username is required')
187
-
188
- if not user_data.get('email'):
189
- errors.append('Email is required')
190
-
191
- if not user_data.get('password'):
192
- errors.append('Password is required')
193
-
194
- # Validate email format
195
- if user_data.get('email'):
196
- try:
197
- validate_email(user_data['email'])
198
- except ValidationError:
199
- errors.append('Invalid email format')
200
-
201
- # Check if user already exists
202
- if user_data.get('username') and User.objects.filter(username=user_data['username']).exists():
203
- errors.append('Username already exists')
204
-
205
- if user_data.get('email') and User.objects.filter(email=user_data['email']).exists():
206
- errors.append('Email already exists')
207
-
208
- # Password strength
209
- if user_data.get('password') and len(user_data['password']) < 8:
210
- errors.append('Password should be at least 8 characters')
211
-
212
- if errors:
213
- self.stdout.write(self.style.ERROR('❌ Validation errors:'))
214
- for error in errors:
215
- self.stdout.write(f' - {error}')
216
- return False
217
-
218
- return True
7
+ Usage:
8
+ python manage.py superuser
9
+ python manage.py superuser --interactive
10
+ python manage.py superuser --username admin --email admin@example.com --password secret
11
+ """
219
12
 
220
- def create_superuser(self, user_data):
221
- """Create the superuser"""
222
- try:
223
- # Create user
224
- user = User.objects.create_user(
225
- username=user_data['username'],
226
- email=user_data['email'],
227
- password=user_data['password'],
228
- first_name=user_data['first_name'],
229
- last_name=user_data['last_name'],
230
- is_staff=True,
231
- is_superuser=True,
232
- is_active=True
233
- )
234
-
235
- # Save user details to file
236
- self.save_superuser_details(user, user_data['password'])
237
-
238
- self.stdout.write(self.style.SUCCESS(f'✅ Superuser created successfully!'))
239
- self.stdout.write(f'👤 Username: {user.username}')
240
- self.stdout.write(f'📧 Email: {user.email}')
241
- self.stdout.write(f'👑 Is Superuser: {user.is_superuser}')
242
- self.stdout.write(f'🔧 Is Staff: {user.is_staff}')
243
- self.stdout.write(f'✅ Is Active: {user.is_active}')
244
-
245
- # Show next steps
246
- self.show_next_steps()
247
-
248
- except Exception as e:
249
- self.stdout.write(self.style.ERROR(f'❌ Error creating superuser: {e}'))
13
+ from django_cfg.modules.django_admin.management.commands.superuser import Command as SuperuserCommand
250
14
 
251
- def save_superuser_details(self, user, password):
252
- """Save superuser details to file"""
253
- # Create superusers directory
254
- superusers_dir = Path('superusers')
255
- superusers_dir.mkdir(exist_ok=True)
256
-
257
- # Create details file
258
- timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
259
- filename = f"superuser_{user.username}_{timestamp}.txt"
260
- filepath = superusers_dir / filename
261
-
262
- with open(filepath, 'w') as f:
263
- f.write(f"Superuser Details\n")
264
- f.write(f"================\n\n")
265
- f.write(f"Username: {user.username}\n")
266
- f.write(f"Email: {user.email}\n")
267
- f.write(f"First Name: {user.first_name}\n")
268
- f.write(f"Is Superuser: {user.is_superuser}\n")
269
- f.write(f"Is Staff: {user.is_staff}\n")
270
- f.write(f"Is Active: {user.is_active}\n")
271
- f.write(f"Date Created: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
272
- f.write(f"\n⚠️ IMPORTANT: Store this password securely!\n")
273
- f.write(f"Password: {password}\n")
274
-
275
- self.stdout.write(f'💾 Superuser details saved to: {filepath}')
276
15
 
277
- def show_next_steps(self):
278
- """Show next steps after creating superuser"""
279
- self.stdout.write(self.style.SUCCESS('\n🎉 Next Steps:'))
280
- self.stdout.write('1. 🚀 Start your Django server: python manage.py runserver')
281
- self.stdout.write('2. 🌐 Visit Django admin: http://localhost:8000/admin/')
282
- self.stdout.write('3. 🔑 Login with your superuser credentials')
283
- self.stdout.write('4. ⚙️ Configure your application settings')
284
- self.stdout.write('5. 📚 Read the Django Config Toolkit documentation')
285
-
286
- # Show health check
287
- self.stdout.write('\n🔍 Health Check:')
288
- try:
289
- call_command('check', verbosity=0)
290
- self.stdout.write('✅ Django configuration is valid')
291
- except Exception as e:
292
- self.stdout.write(f'⚠️ Django configuration issues: {e}')
16
+ class Command(SuperuserCommand):
17
+ """
18
+ Alias for superuser command.
293
19
 
294
- def check_existing_superusers(self):
295
- """Check existing superusers"""
296
- superusers = User.objects.filter(is_superuser=True)
297
- if superusers.exists():
298
- self.stdout.write(self.style.WARNING(f'⚠️ Found {superusers.count()} existing superuser(s):'))
299
- for user in superusers:
300
- self.stdout.write(f' - {user.username} ({user.email})')
301
- return True
302
- return False
20
+ Simply inherits from SuperuserCommand without any changes.
21
+ """
22
+ pass
@@ -1,226 +1,23 @@
1
1
  """
2
- Django management command for clearing task queues.
2
+ Django-CFG wrapper for task_clear command.
3
3
 
4
- This command provides utilities for clearing failed tasks,
5
- specific queues, or all tasks from the Dramatiq system.
6
- """
4
+ This is a simple alias for django_tasks.management.commands.task_clear.
5
+ All logic is in django_tasks module.
7
6
 
8
- from django.core.management.base import BaseCommand, CommandError
9
- from django.conf import settings
10
- from typing import Any, Optional, List
11
- import logging
12
- from django_cfg.modules.django_logging import get_logger
7
+ Usage:
8
+ python manage.py task_clear
9
+ python manage.py task_clear --queue default
10
+ python manage.py task_clear --failed-only
11
+ python manage.py task_clear --confirm
12
+ """
13
13
 
14
- logger = get_logger('task_clear')
14
+ from django_cfg.modules.django_tasks.management.commands.task_clear import Command as TaskClearCommand
15
15
 
16
16
 
17
- class Command(BaseCommand):
17
+ class Command(TaskClearCommand):
18
18
  """
19
- Clear tasks from Dramatiq queues.
19
+ Alias for task_clear command.
20
20
 
21
- Provides options to:
22
- - Clear all tasks from specific queues
23
- - Clear only failed tasks
24
- - Clear all tasks from all queues
21
+ Simply inherits from TaskClearCommand without any changes.
25
22
  """
26
-
27
- # Web execution metadata
28
- web_executable = False
29
- requires_input = True
30
- is_destructive = True
31
-
32
- help = "Clear tasks from Dramatiq queues"
33
-
34
- def add_arguments(self, parser):
35
- """Add command line arguments."""
36
- parser.add_argument(
37
- "--queue",
38
- type=str,
39
- help="Specific queue to clear (default: all queues)",
40
- )
41
- parser.add_argument(
42
- "--failed-only",
43
- action="store_true",
44
- help="Clear only failed tasks",
45
- )
46
- parser.add_argument(
47
- "--confirm",
48
- action="store_true",
49
- help="Skip confirmation prompt",
50
- )
51
- parser.add_argument(
52
- "--dry-run",
53
- action="store_true",
54
- help="Show what would be cleared without actually clearing",
55
- )
56
-
57
- def handle(self, *args, **options):
58
- """Handle the command execution."""
59
- logger.info("Starting task_clear command")
60
-
61
- try:
62
- # Import here to avoid issues if dramatiq is not installed
63
- from django_cfg.modules.django_tasks import get_task_service
64
-
65
- # Get task service
66
- task_service = get_task_service()
67
-
68
- # Check if task system is enabled
69
- if not task_service.is_enabled():
70
- raise CommandError(
71
- "Task system is not enabled. "
72
- "Please configure 'tasks' in your Django-CFG configuration."
73
- )
74
-
75
- # Get task manager
76
- manager = task_service.manager
77
- if not manager:
78
- raise CommandError("Task manager not available")
79
-
80
- # Get configuration
81
- config = task_service.config
82
- if not config:
83
- raise CommandError("Task configuration not available")
84
-
85
- # Determine queues to clear
86
- if options.get("queue"):
87
- queues_to_clear = [options["queue"]]
88
- # Validate queue exists
89
- if options["queue"] not in config.get_effective_queues():
90
- self.stdout.write(
91
- self.style.WARNING(
92
- f"Queue '{options['queue']}' not in configured queues: "
93
- f"{', '.join(config.get_effective_queues())}"
94
- )
95
- )
96
- else:
97
- queues_to_clear = config.get_effective_queues()
98
-
99
- # Show what will be cleared
100
- self._show_clear_plan(queues_to_clear, options)
101
-
102
- if options["dry_run"]:
103
- self.stdout.write(
104
- self.style.SUCCESS("Dry run completed - no tasks were cleared")
105
- )
106
- return
107
-
108
- # Confirm action
109
- if not options["confirm"]:
110
- if not self._confirm_clear(queues_to_clear, options):
111
- self.stdout.write("Operation cancelled")
112
- return
113
-
114
- # Perform clearing
115
- self._clear_queues(manager, queues_to_clear, options)
116
-
117
- except ImportError:
118
- raise CommandError(
119
- "Dramatiq dependencies not installed. "
120
- "Install with: pip install django-cfg[tasks]"
121
- )
122
- except Exception as e:
123
- logger.exception("Failed to clear tasks")
124
- raise CommandError(f"Failed to clear tasks: {e}")
125
-
126
- def _show_clear_plan(self, queues: List[str], options):
127
- """Show what will be cleared."""
128
- self.stdout.write(
129
- self.style.SUCCESS("=== Clear Plan ===")
130
- )
131
-
132
- if options.get("failed_only"):
133
- self.stdout.write("Action: Clear FAILED tasks only")
134
- else:
135
- self.stdout.write("Action: Clear ALL tasks")
136
-
137
- self.stdout.write(f"Queues: {', '.join(queues)}")
138
-
139
- # Get current queue statistics
140
- try:
141
- from django_cfg.modules.django_tasks import get_task_service
142
- task_service = get_task_service()
143
- manager = task_service.manager
144
-
145
- if manager:
146
- queue_stats = manager.get_queue_stats()
147
-
148
- self.stdout.write("\nCurrent Queue Statistics:")
149
- for stat in queue_stats:
150
- if stat["name"] in queues:
151
- name = stat["name"]
152
- pending = stat.get("pending", 0)
153
- failed = stat.get("failed", 0)
154
-
155
- if options.get("failed_only"):
156
- self.stdout.write(f" {name}: {failed} failed tasks")
157
- else:
158
- total = pending + stat.get("running", 0) + failed
159
- self.stdout.write(f" {name}: {total} total tasks")
160
- except Exception as e:
161
- self.stdout.write(f"Could not get queue statistics: {e}")
162
-
163
- self.stdout.write()
164
-
165
- def _confirm_clear(self, queues: List[str], options) -> bool:
166
- """Confirm the clear operation with user."""
167
- if options.get("failed_only"):
168
- action = "clear FAILED tasks"
169
- else:
170
- action = "clear ALL tasks"
171
-
172
- queue_list = ", ".join(queues)
173
-
174
- self.stdout.write(
175
- self.style.WARNING(
176
- f"This will {action} from queues: {queue_list}"
177
- )
178
- )
179
-
180
- response = input("Are you sure? [y/N]: ").lower().strip()
181
- return response in ["y", "yes"]
182
-
183
- def _clear_queues(self, manager, queues: List[str], options):
184
- """Clear the specified queues."""
185
- cleared_count = 0
186
-
187
- self.stdout.write(
188
- self.style.SUCCESS("Starting queue clearing...")
189
- )
190
-
191
- for queue_name in queues:
192
- try:
193
- self.stdout.write(f"Clearing queue: {queue_name}")
194
-
195
- if options.get("failed_only"):
196
- # Clear only failed tasks
197
- # TODO: Implement failed task clearing
198
- # This would require specific Dramatiq broker methods
199
- count = 0 # Placeholder
200
- self.stdout.write(f" Cleared {count} failed tasks")
201
- else:
202
- # Clear all tasks
203
- success = manager.clear_queue(queue_name)
204
- if success:
205
- # TODO: Get actual count of cleared tasks
206
- count = 0 # Placeholder
207
- self.stdout.write(f" Cleared {count} tasks")
208
- cleared_count += count
209
- else:
210
- self.stdout.write(
211
- self.style.ERROR(f" Failed to clear queue: {queue_name}")
212
- )
213
-
214
- except Exception as e:
215
- self.stdout.write(
216
- self.style.ERROR(f" Error clearing queue {queue_name}: {e}")
217
- )
218
-
219
- if cleared_count > 0:
220
- self.stdout.write(
221
- self.style.SUCCESS(f"Successfully cleared {cleared_count} tasks")
222
- )
223
- else:
224
- self.stdout.write(
225
- self.style.WARNING("No tasks were cleared")
226
- )
23
+ pass