django-cfg 1.4.10__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 (181) 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/views/api/currencies.py +49 -6
  8. django_cfg/apps/payments/views/api/webhooks.py +72 -7
  9. django_cfg/apps/payments/views/overview/serializers.py +34 -1
  10. django_cfg/apps/payments/views/overview/views.py +2 -1
  11. django_cfg/apps/payments/views/serializers/payments.py +6 -6
  12. django_cfg/apps/urls.py +106 -45
  13. django_cfg/core/base/config_model.py +2 -2
  14. django_cfg/core/constants.py +1 -1
  15. django_cfg/core/generation/integration_generators/__init__.py +1 -1
  16. django_cfg/core/generation/integration_generators/api.py +72 -49
  17. django_cfg/core/integration/display/startup.py +30 -22
  18. django_cfg/core/integration/url_integration.py +15 -16
  19. django_cfg/dashboard/sections/documentation.py +391 -0
  20. django_cfg/management/commands/check_endpoints.py +11 -160
  21. django_cfg/management/commands/check_settings.py +13 -348
  22. django_cfg/management/commands/clear_constance.py +13 -201
  23. django_cfg/management/commands/create_token.py +13 -321
  24. django_cfg/management/commands/generate_clients.py +23 -0
  25. django_cfg/management/commands/list_urls.py +13 -306
  26. django_cfg/management/commands/migrate_all.py +13 -126
  27. django_cfg/management/commands/migrator.py +13 -396
  28. django_cfg/management/commands/rundramatiq.py +15 -247
  29. django_cfg/management/commands/rundramatiq_simulator.py +12 -429
  30. django_cfg/management/commands/runserver_ngrok.py +15 -160
  31. django_cfg/management/commands/script.py +12 -488
  32. django_cfg/management/commands/show_config.py +12 -215
  33. django_cfg/management/commands/show_urls.py +12 -342
  34. django_cfg/management/commands/superuser.py +15 -295
  35. django_cfg/management/commands/task_clear.py +14 -217
  36. django_cfg/management/commands/task_status.py +13 -248
  37. django_cfg/management/commands/test_email.py +15 -86
  38. django_cfg/management/commands/test_telegram.py +14 -61
  39. django_cfg/management/commands/test_twilio.py +15 -105
  40. django_cfg/management/commands/tree.py +13 -383
  41. django_cfg/management/commands/validate_openapi.py +10 -0
  42. django_cfg/middleware/README.md +1 -1
  43. django_cfg/middleware/user_activity.py +3 -3
  44. django_cfg/models/__init__.py +2 -2
  45. django_cfg/models/api/drf/spectacular.py +6 -6
  46. django_cfg/models/django/__init__.py +2 -2
  47. django_cfg/models/django/openapi.py +238 -0
  48. django_cfg/modules/django_admin/management/__init__.py +0 -0
  49. django_cfg/modules/django_admin/management/commands/__init__.py +0 -0
  50. django_cfg/modules/django_admin/management/commands/check_endpoints.py +169 -0
  51. django_cfg/modules/django_admin/management/commands/check_settings.py +355 -0
  52. django_cfg/modules/django_admin/management/commands/clear_constance.py +208 -0
  53. django_cfg/modules/django_admin/management/commands/create_token.py +328 -0
  54. django_cfg/modules/django_admin/management/commands/list_urls.py +313 -0
  55. django_cfg/modules/django_admin/management/commands/migrate_all.py +133 -0
  56. django_cfg/modules/django_admin/management/commands/migrator.py +403 -0
  57. django_cfg/modules/django_admin/management/commands/script.py +496 -0
  58. django_cfg/modules/django_admin/management/commands/show_config.py +225 -0
  59. django_cfg/modules/django_admin/management/commands/show_urls.py +361 -0
  60. django_cfg/modules/django_admin/management/commands/superuser.py +302 -0
  61. django_cfg/modules/django_admin/management/commands/tree.py +390 -0
  62. django_cfg/modules/django_client/__init__.py +20 -0
  63. django_cfg/modules/django_client/apps.py +35 -0
  64. django_cfg/modules/django_client/core/__init__.py +56 -0
  65. django_cfg/modules/django_client/core/archive/__init__.py +11 -0
  66. django_cfg/modules/django_client/core/archive/manager.py +134 -0
  67. django_cfg/modules/django_client/core/cli/__init__.py +12 -0
  68. django_cfg/modules/django_client/core/cli/main.py +235 -0
  69. django_cfg/modules/django_client/core/config/__init__.py +18 -0
  70. django_cfg/modules/django_client/core/config/config.py +188 -0
  71. django_cfg/modules/django_client/core/config/group.py +101 -0
  72. django_cfg/modules/django_client/core/config/service.py +209 -0
  73. django_cfg/modules/django_client/core/generator/__init__.py +115 -0
  74. django_cfg/modules/django_client/core/generator/base.py +767 -0
  75. django_cfg/modules/django_client/core/generator/python.py +751 -0
  76. django_cfg/modules/django_client/core/generator/templates/python/__init__.py.jinja +9 -0
  77. django_cfg/modules/django_client/core/generator/templates/python/api_wrapper.py.jinja +130 -0
  78. django_cfg/modules/django_client/core/generator/templates/python/app_init.py.jinja +6 -0
  79. django_cfg/modules/django_client/core/generator/templates/python/client/app_client.py.jinja +18 -0
  80. django_cfg/modules/django_client/core/generator/templates/python/client/flat_client.py.jinja +38 -0
  81. django_cfg/modules/django_client/core/generator/templates/python/client/main_client.py.jinja +50 -0
  82. django_cfg/modules/django_client/core/generator/templates/python/client/main_client_file.py.jinja +13 -0
  83. django_cfg/modules/django_client/core/generator/templates/python/client/operation_method.py.jinja +7 -0
  84. django_cfg/modules/django_client/core/generator/templates/python/client/sub_client.py.jinja +11 -0
  85. django_cfg/modules/django_client/core/generator/templates/python/client_file.py.jinja +13 -0
  86. django_cfg/modules/django_client/core/generator/templates/python/main_init.py.jinja +50 -0
  87. django_cfg/modules/django_client/core/generator/templates/python/models/app_models.py.jinja +17 -0
  88. django_cfg/modules/django_client/core/generator/templates/python/models/enum_class.py.jinja +15 -0
  89. django_cfg/modules/django_client/core/generator/templates/python/models/enums.py.jinja +8 -0
  90. django_cfg/modules/django_client/core/generator/templates/python/models/models.py.jinja +17 -0
  91. django_cfg/modules/django_client/core/generator/templates/python/models/schema_class.py.jinja +19 -0
  92. django_cfg/modules/django_client/core/generator/templates/python/utils/logger.py.jinja +255 -0
  93. django_cfg/modules/django_client/core/generator/templates/python/utils/schema.py.jinja +12 -0
  94. django_cfg/modules/django_client/core/generator/templates/typescript/app_index.ts.jinja +2 -0
  95. django_cfg/modules/django_client/core/generator/templates/typescript/client/app_client.ts.jinja +18 -0
  96. django_cfg/modules/django_client/core/generator/templates/typescript/client/client.ts.jinja +327 -0
  97. django_cfg/modules/django_client/core/generator/templates/typescript/client/flat_client.ts.jinja +109 -0
  98. django_cfg/modules/django_client/core/generator/templates/typescript/client/main_client_file.ts.jinja +9 -0
  99. django_cfg/modules/django_client/core/generator/templates/typescript/client/operation.ts.jinja +61 -0
  100. django_cfg/modules/django_client/core/generator/templates/typescript/client/sub_client.ts.jinja +15 -0
  101. django_cfg/modules/django_client/core/generator/templates/typescript/client_file.ts.jinja +9 -0
  102. django_cfg/modules/django_client/core/generator/templates/typescript/index.ts.jinja +5 -0
  103. django_cfg/modules/django_client/core/generator/templates/typescript/main_index.ts.jinja +206 -0
  104. django_cfg/modules/django_client/core/generator/templates/typescript/models/app_models.ts.jinja +8 -0
  105. django_cfg/modules/django_client/core/generator/templates/typescript/models/enums.ts.jinja +4 -0
  106. django_cfg/modules/django_client/core/generator/templates/typescript/models/models.ts.jinja +8 -0
  107. django_cfg/modules/django_client/core/generator/templates/typescript/utils/errors.ts.jinja +114 -0
  108. django_cfg/modules/django_client/core/generator/templates/typescript/utils/http.ts.jinja +98 -0
  109. django_cfg/modules/django_client/core/generator/templates/typescript/utils/logger.ts.jinja +251 -0
  110. django_cfg/modules/django_client/core/generator/templates/typescript/utils/schema.ts.jinja +7 -0
  111. django_cfg/modules/django_client/core/generator/templates/typescript/utils/storage.ts.jinja +114 -0
  112. django_cfg/modules/django_client/core/generator/typescript.py +872 -0
  113. django_cfg/modules/django_client/core/groups/__init__.py +13 -0
  114. django_cfg/modules/django_client/core/groups/detector.py +178 -0
  115. django_cfg/modules/django_client/core/groups/manager.py +314 -0
  116. django_cfg/modules/django_client/core/ir/__init__.py +57 -0
  117. django_cfg/modules/django_client/core/ir/context.py +387 -0
  118. django_cfg/modules/django_client/core/ir/operation.py +518 -0
  119. django_cfg/modules/django_client/core/ir/schema.py +353 -0
  120. django_cfg/modules/django_client/core/parser/__init__.py +74 -0
  121. django_cfg/modules/django_client/core/parser/base.py +648 -0
  122. django_cfg/modules/django_client/core/parser/models/__init__.py +74 -0
  123. django_cfg/modules/django_client/core/parser/models/base.py +212 -0
  124. django_cfg/modules/django_client/core/parser/models/components.py +160 -0
  125. django_cfg/modules/django_client/core/parser/models/openapi.py +203 -0
  126. django_cfg/modules/django_client/core/parser/models/operation.py +207 -0
  127. django_cfg/modules/django_client/core/parser/models/schema.py +266 -0
  128. django_cfg/modules/django_client/core/parser/openapi30.py +56 -0
  129. django_cfg/modules/django_client/core/parser/openapi31.py +64 -0
  130. django_cfg/modules/django_client/core/validation/__init__.py +22 -0
  131. django_cfg/modules/django_client/core/validation/checker.py +134 -0
  132. django_cfg/modules/django_client/core/validation/fixer.py +216 -0
  133. django_cfg/modules/django_client/core/validation/reporter.py +480 -0
  134. django_cfg/modules/django_client/core/validation/rules/__init__.py +11 -0
  135. django_cfg/modules/django_client/core/validation/rules/base.py +96 -0
  136. django_cfg/modules/django_client/core/validation/rules/type_hints.py +288 -0
  137. django_cfg/modules/django_client/core/validation/safety.py +266 -0
  138. django_cfg/modules/django_client/management/__init__.py +3 -0
  139. django_cfg/modules/django_client/management/commands/__init__.py +3 -0
  140. django_cfg/modules/django_client/management/commands/generate_client.py +422 -0
  141. django_cfg/modules/django_client/management/commands/validate_openapi.py +343 -0
  142. django_cfg/modules/django_client/spectacular/__init__.py +9 -0
  143. django_cfg/modules/django_client/spectacular/enum_naming.py +192 -0
  144. django_cfg/modules/django_client/urls.py +72 -0
  145. django_cfg/modules/django_email/management/__init__.py +0 -0
  146. django_cfg/modules/django_email/management/commands/__init__.py +0 -0
  147. django_cfg/modules/django_email/management/commands/test_email.py +93 -0
  148. django_cfg/modules/django_logging/django_logger.py +6 -6
  149. django_cfg/modules/django_ngrok/management/__init__.py +0 -0
  150. django_cfg/modules/django_ngrok/management/commands/__init__.py +0 -0
  151. django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +167 -0
  152. django_cfg/modules/django_tasks/management/__init__.py +0 -0
  153. django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
  154. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +254 -0
  155. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +437 -0
  156. django_cfg/modules/django_tasks/management/commands/task_clear.py +226 -0
  157. django_cfg/modules/django_tasks/management/commands/task_status.py +257 -0
  158. django_cfg/modules/django_telegram/management/__init__.py +0 -0
  159. django_cfg/modules/django_telegram/management/commands/__init__.py +0 -0
  160. django_cfg/modules/django_telegram/management/commands/test_telegram.py +68 -0
  161. django_cfg/modules/django_twilio/management/__init__.py +0 -0
  162. django_cfg/modules/django_twilio/management/commands/__init__.py +0 -0
  163. django_cfg/modules/django_twilio/management/commands/test_twilio.py +112 -0
  164. django_cfg/modules/django_unfold/callbacks/main.py +16 -5
  165. django_cfg/modules/django_unfold/callbacks/revolution.py +41 -36
  166. django_cfg/pyproject.toml +2 -6
  167. django_cfg/registry/third_party.py +5 -7
  168. django_cfg/routing/callbacks.py +1 -1
  169. django_cfg/static/admin/css/prose-unfold.css +666 -0
  170. django_cfg/templates/admin/index.html +8 -0
  171. django_cfg/templates/admin/index_new.html +13 -0
  172. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +15 -3
  173. django_cfg/templates/admin/sections/documentation_section.html +172 -0
  174. django_cfg/templates/admin/snippets/tabs/documentation_tab.html +231 -0
  175. {django_cfg-1.4.10.dist-info → django_cfg-1.4.11.dist-info}/METADATA +2 -2
  176. {django_cfg-1.4.10.dist-info → django_cfg-1.4.11.dist-info}/RECORD +180 -59
  177. django_cfg/management/commands/generate.py +0 -107
  178. /django_cfg/models/django/{revolution.py → revolution_legacy.py} +0 -0
  179. {django_cfg-1.4.10.dist-info → django_cfg-1.4.11.dist-info}/WHEEL +0 -0
  180. {django_cfg-1.4.10.dist-info → django_cfg-1.4.11.dist-info}/entry_points.txt +0 -0
  181. {django_cfg-1.4.10.dist-info → django_cfg-1.4.11.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,496 @@
1
+ """
2
+ Script Command for Django Config Toolkit
3
+ Run custom scripts and manage Django applications.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import subprocess
9
+ import importlib
10
+ from pathlib import Path
11
+ from django.core.management.base import BaseCommand
12
+ from django.core.management import call_command
13
+ from django.conf import settings
14
+ import questionary
15
+ from datetime import datetime
16
+ from django_cfg.modules.django_logging import get_logger
17
+
18
+
19
+ logger = get_logger('script')
20
+
21
+ class Command(BaseCommand):
22
+ # Web execution metadata
23
+ web_executable = False
24
+ requires_input = True
25
+ is_destructive = False
26
+
27
+ help = 'Run custom scripts and manage Django applications'
28
+
29
+ def add_arguments(self, parser):
30
+ parser.add_argument(
31
+ '--script',
32
+ type=str,
33
+ help='Script name to run'
34
+ )
35
+ parser.add_argument(
36
+ '--list',
37
+ action='store_true',
38
+ help='List available scripts'
39
+ )
40
+ parser.add_argument(
41
+ '--create',
42
+ type=str,
43
+ help='Create new script template'
44
+ )
45
+ parser.add_argument(
46
+ '--shell',
47
+ action='store_true',
48
+ help='Open Django shell'
49
+ )
50
+ parser.add_argument(
51
+ '--check',
52
+ action='store_true',
53
+ help='Run Django system check'
54
+ )
55
+
56
+ def handle(self, *args, **options):
57
+ logger.info("Starting script command")
58
+ if options['list']:
59
+ self.list_scripts()
60
+ elif options['create']:
61
+ self.create_script_template(options['create'])
62
+ elif options['shell']:
63
+ self.open_django_shell()
64
+ elif options['check']:
65
+ self.run_django_check()
66
+ elif options['script']:
67
+ self.run_script(options['script'])
68
+ else:
69
+ self.show_interactive_menu()
70
+
71
+ def show_interactive_menu(self):
72
+ """Show interactive menu with script options"""
73
+ self.stdout.write(self.style.SUCCESS('\n📜 Script Management Tool - Django Config Toolkit\n'))
74
+
75
+ choices = [
76
+ questionary.Choice('📋 List Available Scripts', value='list'),
77
+ questionary.Choice('➕ Create New Script', value='create'),
78
+ questionary.Choice('▶️ Run Script', value='run'),
79
+ questionary.Choice('🐚 Open Django Shell', value='shell'),
80
+ questionary.Choice('🔍 Run System Check', value='check'),
81
+ questionary.Choice('🧹 Clean Project', value='clean'),
82
+ questionary.Choice('📊 Show Project Info', value='info'),
83
+ questionary.Choice('❌ Exit', value='exit')
84
+ ]
85
+
86
+ choice = questionary.select(
87
+ 'Select option:',
88
+ choices=choices
89
+ ).ask()
90
+
91
+ if choice == 'list':
92
+ self.list_scripts()
93
+ elif choice == 'create':
94
+ self.create_script_interactive()
95
+ elif choice == 'run':
96
+ self.run_script_interactive()
97
+ elif choice == 'shell':
98
+ self.open_django_shell()
99
+ elif choice == 'check':
100
+ self.run_django_check()
101
+ elif choice == 'clean':
102
+ self.clean_project()
103
+ elif choice == 'info':
104
+ self.show_project_info()
105
+ elif choice == 'exit':
106
+ self.stdout.write('Goodbye! 👋')
107
+ return
108
+
109
+ def list_scripts(self):
110
+ """List available scripts"""
111
+ self.stdout.write(self.style.SUCCESS('📋 Available Scripts\n'))
112
+
113
+ # Check for scripts directory
114
+ scripts_dir = Path('scripts')
115
+ if not scripts_dir.exists():
116
+ self.stdout.write(' 📁 No scripts directory found')
117
+ self.stdout.write(' 💡 Use --create to create your first script')
118
+ return
119
+
120
+ # List Python scripts
121
+ python_scripts = list(scripts_dir.glob('*.py'))
122
+ if python_scripts:
123
+ self.stdout.write(' 🐍 Python Scripts:')
124
+ for script in python_scripts:
125
+ if script.name != '__init__.py':
126
+ self.stdout.write(f' - {script.stem}')
127
+ else:
128
+ self.stdout.write(' 🐍 No Python scripts found')
129
+
130
+ # List shell scripts
131
+ shell_scripts = list(scripts_dir.glob('*.sh'))
132
+ if shell_scripts:
133
+ self.stdout.write(' 🐚 Shell Scripts:')
134
+ for script in shell_scripts:
135
+ self.stdout.write(f' - {script.stem}')
136
+
137
+ # List other scripts
138
+ other_scripts = [s for s in scripts_dir.iterdir() if s.is_file() and s.suffix not in ['.py', '.sh']]
139
+ if other_scripts:
140
+ self.stdout.write(' 📄 Other Scripts:')
141
+ for script in other_scripts:
142
+ self.stdout.write(f' - {script.name}')
143
+
144
+ def create_script_interactive(self):
145
+ """Create script interactively"""
146
+ self.stdout.write(self.style.SUCCESS('➕ Create New Script\n'))
147
+
148
+ # Get script name
149
+ script_name = questionary.text('Script name:').ask()
150
+ if not script_name:
151
+ self.stdout.write(self.style.ERROR('❌ Script name is required'))
152
+ return
153
+
154
+ # Get script type
155
+ script_type = questionary.select(
156
+ 'Script type:',
157
+ choices=['Python Script', 'Shell Script', 'Django Management Command']
158
+ ).ask()
159
+
160
+ # Create script
161
+ if script_type == 'Python Script':
162
+ self.create_python_script(script_name)
163
+ elif script_type == 'Shell Script':
164
+ self.create_shell_script(script_name)
165
+ elif script_type == 'Django Management Command':
166
+ self.create_django_command(script_name)
167
+
168
+ def create_script_template(self, script_name):
169
+ """Create script template"""
170
+ self.create_python_script(script_name)
171
+
172
+ def create_python_script(self, script_name):
173
+ """Create Python script template"""
174
+ # Create scripts directory
175
+ scripts_dir = Path('scripts')
176
+ scripts_dir.mkdir(exist_ok=True)
177
+
178
+ # Create __init__.py if it doesn't exist
179
+ init_file = scripts_dir / '__init__.py'
180
+ if not init_file.exists():
181
+ init_file.touch()
182
+
183
+ # Create script file
184
+ script_path = scripts_dir / f'{script_name}.py'
185
+
186
+ script_content = f'''"""
187
+ {script_name.title()} Script
188
+ Auto-generated script for Django Config Toolkit.
189
+ """
190
+
191
+ import os
192
+ import sys
193
+ from pathlib import Path
194
+ from django.core.management import execute_from_command_line
195
+ from django.conf import settings
196
+
197
+ # Add project root to Python path
198
+ project_root = Path(__file__).resolve().parent.parent
199
+ sys.path.insert(0, str(project_root))
200
+
201
+ # Setup Django environment
202
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
203
+
204
+ # Import Django
205
+ import django
206
+ django.setup()
207
+
208
+
209
+ def main():
210
+ """Main function for {script_name} script."""
211
+ print(f"🚀 Running {script_name} script...")
212
+
213
+ # Your script logic here
214
+ # You can use Django settings: from django.conf import settings
215
+ # Or DjangoConfig: from django_cfg.core.state import get_current_config
216
+
217
+ print("✅ Script completed successfully!")
218
+
219
+
220
+ if __name__ == '__main__':
221
+ main()
222
+ '''
223
+
224
+ with open(script_path, 'w') as f:
225
+ f.write(script_content)
226
+
227
+ self.stdout.write(f' 📄 Python script created: {script_path}')
228
+ self.stdout.write(' 💡 Edit the script to add your custom logic')
229
+
230
+ def create_shell_script(self, script_name):
231
+ """Create shell script template"""
232
+ # Create scripts directory
233
+ scripts_dir = Path('scripts')
234
+ scripts_dir.mkdir(exist_ok=True)
235
+
236
+ # Create script file
237
+ script_path = scripts_dir / f'{script_name}.sh'
238
+
239
+ script_content = f'''#!/bin/bash
240
+
241
+ # {script_name.title()} Script
242
+ # Auto-generated shell script for Django Config Toolkit.
243
+
244
+ set -e # Exit on error
245
+
246
+ echo "🚀 Running {script_name} script..."
247
+
248
+ # Your shell script logic here
249
+ echo "✅ Script completed successfully!"
250
+ '''
251
+
252
+ with open(script_path, 'w') as f:
253
+ f.write(script_content)
254
+
255
+ # Make executable
256
+ script_path.chmod(0o755)
257
+
258
+ self.stdout.write(f' 📄 Shell script created: {script_path}')
259
+ self.stdout.write(' 💡 Edit the script to add your custom logic')
260
+
261
+ def create_django_command(self, command_name):
262
+ """Create Django management command template"""
263
+ # Create management commands directory
264
+ commands_dir = Path('management/commands')
265
+ commands_dir.mkdir(parents=True, exist_ok=True)
266
+
267
+ # Create __init__.py files
268
+ (commands_dir.parent / '__init__.py').touch()
269
+ (commands_dir / '__init__.py').touch()
270
+
271
+ # Create command file
272
+ command_path = commands_dir / f'{command_name}.py'
273
+
274
+ command_content = f'''"""
275
+ {command_name.title()} Command
276
+ Auto-generated Django management command.
277
+ """
278
+
279
+ from django.core.management.base import BaseCommand
280
+ from django.conf import settings
281
+
282
+
283
+ class Command(BaseCommand):
284
+ help = '{command_name.title()} command description'
285
+
286
+ def add_arguments(self, parser):
287
+ # Add command arguments here
288
+ pass
289
+
290
+ def handle(self, *args, **options):
291
+ """Handle the command."""
292
+ self.stdout.write(self.style.SUCCESS(f'🚀 Running {command_name} command...'))
293
+
294
+ # Your command logic here
295
+ # You can use Django settings: settings.DEBUG, etc.
296
+ # Or DjangoConfig: from django_cfg.core.state import get_current_config
297
+
298
+ self.stdout.write(self.style.SUCCESS('✅ Command completed successfully!'))
299
+ '''
300
+
301
+ with open(command_path, 'w') as f:
302
+ f.write(command_content)
303
+
304
+ self.stdout.write(f' 📄 Django command created: {command_path}')
305
+ self.stdout.write(' 💡 Run with: python manage.py {command_name}')
306
+
307
+ def run_script_interactive(self):
308
+ """Run script interactively"""
309
+ self.stdout.write(self.style.SUCCESS('▶️ Run Script\n'))
310
+
311
+ # List available scripts
312
+ scripts_dir = Path('scripts')
313
+ if not scripts_dir.exists():
314
+ self.stdout.write('❌ No scripts directory found')
315
+ return
316
+
317
+ # Get available scripts
318
+ python_scripts = [s.stem for s in scripts_dir.glob('*.py') if s.name != '__init__.py']
319
+ shell_scripts = [s.stem for s in scripts_dir.glob('*.sh')]
320
+
321
+ if not python_scripts and not shell_scripts:
322
+ self.stdout.write('❌ No scripts found')
323
+ return
324
+
325
+ # Create choices
326
+ choices = []
327
+ if python_scripts:
328
+ choices.append(questionary.Choice('🐍 Python Scripts', value='python'))
329
+ if shell_scripts:
330
+ choices.append(questionary.Choice('🐚 Shell Scripts', value='shell'))
331
+
332
+ script_type = questionary.select('Script type:', choices=choices).ask()
333
+
334
+ if script_type == 'python':
335
+ script_name = questionary.select('Select script:', choices=python_scripts).ask()
336
+ self.run_python_script(script_name)
337
+ elif script_type == 'shell':
338
+ script_name = questionary.select('Select script:', choices=shell_scripts).ask()
339
+ self.run_shell_script(script_name)
340
+
341
+ def run_script(self, script_name):
342
+ """Run specific script"""
343
+ script_path = Path('scripts') / f'{script_name}.py'
344
+ shell_script_path = Path('scripts') / f'{script_name}.sh'
345
+
346
+ if script_path.exists():
347
+ self.run_python_script(script_name)
348
+ elif shell_script_path.exists():
349
+ self.run_shell_script(script_name)
350
+ else:
351
+ self.stdout.write(self.style.ERROR(f'❌ Script {script_name} not found'))
352
+
353
+ def run_python_script(self, script_name):
354
+ """Run Python script"""
355
+ script_path = Path('scripts') / f'{script_name}.py'
356
+
357
+ if not script_path.exists():
358
+ self.stdout.write(self.style.ERROR(f'❌ Script {script_name} not found'))
359
+ return
360
+
361
+ self.stdout.write(self.style.SUCCESS(f'🚀 Running Python script: {script_name}'))
362
+
363
+ try:
364
+ # Run script in Django context
365
+ result = subprocess.run([
366
+ sys.executable, str(script_path)
367
+ ], capture_output=True, text=True, cwd=Path.cwd())
368
+
369
+ if result.stdout:
370
+ self.stdout.write(result.stdout)
371
+ if result.stderr:
372
+ self.stdout.write(self.style.WARNING(result.stderr))
373
+
374
+ if result.returncode == 0:
375
+ self.stdout.write(self.style.SUCCESS('✅ Script completed successfully!'))
376
+ else:
377
+ self.stdout.write(self.style.ERROR('❌ Script failed'))
378
+
379
+ except Exception as e:
380
+ self.stdout.write(self.style.ERROR(f'❌ Error running script: {e}'))
381
+
382
+ def run_shell_script(self, script_name):
383
+ """Run shell script"""
384
+ script_path = Path('scripts') / f'{script_name}.sh'
385
+
386
+ if not script_path.exists():
387
+ self.stdout.write(self.style.ERROR(f'❌ Script {script_name} not found'))
388
+ return
389
+
390
+ self.stdout.write(self.style.SUCCESS(f'🚀 Running shell script: {script_name}'))
391
+
392
+ try:
393
+ result = subprocess.run([
394
+ 'bash', str(script_path)
395
+ ], capture_output=True, text=True, cwd=Path.cwd())
396
+
397
+ if result.stdout:
398
+ self.stdout.write(result.stdout)
399
+ if result.stderr:
400
+ self.stdout.write(self.style.WARNING(result.stderr))
401
+
402
+ if result.returncode == 0:
403
+ self.stdout.write(self.style.SUCCESS('✅ Script completed successfully!'))
404
+ else:
405
+ self.stdout.write(self.style.ERROR('❌ Script failed'))
406
+
407
+ except Exception as e:
408
+ self.stdout.write(self.style.ERROR(f'❌ Error running script: {e}'))
409
+
410
+ def open_django_shell(self):
411
+ """Open Django shell"""
412
+ self.stdout.write(self.style.SUCCESS('🐚 Opening Django Shell...'))
413
+
414
+ try:
415
+ call_command('shell')
416
+ except Exception as e:
417
+ self.stdout.write(self.style.ERROR(f'❌ Error opening Django shell: {e}'))
418
+
419
+ def run_django_check(self):
420
+ """Run Django system check"""
421
+ self.stdout.write(self.style.SUCCESS('🔍 Running Django System Check...'))
422
+
423
+ try:
424
+ call_command('check', verbosity=2)
425
+ self.stdout.write(self.style.SUCCESS('✅ System check completed'))
426
+ except Exception as e:
427
+ self.stdout.write(self.style.ERROR(f'❌ System check failed: {e}'))
428
+
429
+ def clean_project(self):
430
+ """Clean project files"""
431
+ self.stdout.write(self.style.SUCCESS('🧹 Cleaning Project...'))
432
+
433
+ # Files to clean
434
+ files_to_clean = [
435
+ '*.pyc',
436
+ '__pycache__',
437
+ '.pytest_cache',
438
+ '*.log',
439
+ '*.sqlite3',
440
+ 'media/',
441
+ 'staticfiles/',
442
+ ]
443
+
444
+ for pattern in files_to_clean:
445
+ if '*' in pattern:
446
+ # Handle glob patterns
447
+ for file_path in Path('.').glob(pattern):
448
+ if file_path.is_file():
449
+ file_path.unlink()
450
+ self.stdout.write(f' 🗑️ Deleted: {file_path}')
451
+ else:
452
+ # Handle directories
453
+ dir_path = Path(pattern)
454
+ if dir_path.exists() and dir_path.is_dir():
455
+ import shutil
456
+ shutil.rmtree(dir_path)
457
+ self.stdout.write(f' 🗑️ Deleted directory: {dir_path}')
458
+
459
+ self.stdout.write(self.style.SUCCESS('✅ Project cleaned'))
460
+
461
+ def show_project_info(self):
462
+ """Show project information"""
463
+ self.stdout.write(self.style.SUCCESS('📊 Project Information\n'))
464
+
465
+ # Django version
466
+ import django
467
+ self.stdout.write(f'🐍 Python: {sys.version}')
468
+ self.stdout.write(f'🎯 Django: {django.get_version()}')
469
+
470
+ # Project settings
471
+ self.stdout.write(f'📁 Project: {settings.SETTINGS_MODULE}')
472
+ self.stdout.write(f'🔧 Debug: {settings.DEBUG}')
473
+ self.stdout.write(f'🌐 Allowed Hosts: {settings.ALLOWED_HOSTS}')
474
+
475
+ # Installed apps count
476
+ self.stdout.write(f'📦 Installed Apps: {len(settings.INSTALLED_APPS)}')
477
+
478
+ # Database info
479
+ if hasattr(settings, 'DATABASES'):
480
+ self.stdout.write(f'🗄️ Databases: {len(settings.DATABASES)}')
481
+ for db_name in settings.DATABASES:
482
+ engine = settings.DATABASES[db_name].get('ENGINE', 'Unknown')
483
+ self.stdout.write(f' - {db_name}: {engine}')
484
+
485
+ # Django-CFG info
486
+ try:
487
+ from django_cfg.core.state import get_current_config
488
+ config = get_current_config()
489
+ if config:
490
+ self.stdout.write(f'⚙️ Django-CFG: Loaded')
491
+ if hasattr(config, 'project_name'):
492
+ self.stdout.write(f' - Project: {config.project_name}')
493
+ else:
494
+ self.stdout.write(f'⚠️ Django-CFG: No config loaded')
495
+ except Exception as e:
496
+ self.stdout.write(f'❌ Django-CFG: Error - {e}')