django-cfg 1.3.9__py3-none-any.whl → 1.3.13__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 (188) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/payments/admin/networks_admin.py +12 -1
  4. django_cfg/apps/payments/admin/payments_admin.py +13 -0
  5. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
  6. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  7. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  8. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  9. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  10. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  11. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  12. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  13. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
  14. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  15. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
  16. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  17. django_cfg/apps/payments/config/__init__.py +14 -15
  18. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  19. django_cfg/apps/payments/config/helpers.py +8 -13
  20. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  21. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  22. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  23. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  24. django_cfg/apps/payments/models/payments.py +94 -0
  25. django_cfg/apps/payments/services/core/base.py +4 -4
  26. django_cfg/apps/payments/services/core/payment_service.py +265 -38
  27. django_cfg/apps/payments/services/providers/base.py +209 -3
  28. django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
  29. django_cfg/apps/payments/services/providers/models/base.py +25 -2
  30. django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
  31. django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
  32. django_cfg/apps/payments/services/providers/registry.py +5 -5
  33. django_cfg/apps/payments/services/types/requests.py +19 -7
  34. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  35. django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
  36. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  37. django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
  38. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  39. django_cfg/apps/payments/urls.py +3 -2
  40. django_cfg/apps/payments/views/api/currencies.py +3 -0
  41. django_cfg/apps/payments/views/serializers/currencies.py +18 -5
  42. django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
  43. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  44. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  45. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  46. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  47. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  48. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  49. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  50. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  51. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  52. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  53. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  54. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  55. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  56. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  57. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  58. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  59. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  60. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  61. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  62. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  63. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  64. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  65. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  66. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  67. django_cfg/apps/tasks/urls.py +2 -2
  68. django_cfg/apps/tasks/urls_admin.py +2 -2
  69. django_cfg/apps/tasks/utils/__init__.py +1 -0
  70. django_cfg/apps/tasks/utils/simulator.py +356 -0
  71. django_cfg/apps/tasks/views/__init__.py +16 -0
  72. django_cfg/apps/tasks/views/api.py +569 -0
  73. django_cfg/apps/tasks/views/dashboard.py +58 -0
  74. django_cfg/core/integration/__init__.py +21 -0
  75. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  76. django_cfg/models/constance.py +0 -11
  77. django_cfg/models/payments.py +137 -3
  78. django_cfg/modules/django_tasks.py +54 -21
  79. django_cfg/registry/core.py +4 -9
  80. django_cfg/template_archive/django_sample.zip +0 -0
  81. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/METADATA +2 -2
  82. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/RECORD +85 -153
  83. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  84. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  85. django_cfg/apps/payments/config/constance/fields.py +0 -69
  86. django_cfg/apps/payments/config/constance/settings.py +0 -160
  87. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
  88. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
  89. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
  90. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  91. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  92. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  93. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  94. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  95. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  96. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  97. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  98. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  99. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  100. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  101. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  102. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  103. django_cfg/apps/tasks/views.py +0 -461
  104. django_cfg/management/commands/app_agent_diagnose.py +0 -470
  105. django_cfg/management/commands/app_agent_generate.py +0 -342
  106. django_cfg/management/commands/app_agent_info.py +0 -308
  107. django_cfg/management/commands/auto_generate.py +0 -486
  108. django_cfg/modules/django_app_agent/__init__.py +0 -87
  109. django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
  110. django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
  111. django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
  112. django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
  113. django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
  114. django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
  115. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
  116. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
  117. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
  118. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
  119. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
  120. django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
  121. django_cfg/modules/django_app_agent/core/__init__.py +0 -33
  122. django_cfg/modules/django_app_agent/core/config.py +0 -300
  123. django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
  124. django_cfg/modules/django_app_agent/models/__init__.py +0 -71
  125. django_cfg/modules/django_app_agent/models/base.py +0 -283
  126. django_cfg/modules/django_app_agent/models/context.py +0 -496
  127. django_cfg/modules/django_app_agent/models/enums.py +0 -481
  128. django_cfg/modules/django_app_agent/models/requests.py +0 -500
  129. django_cfg/modules/django_app_agent/models/responses.py +0 -585
  130. django_cfg/modules/django_app_agent/pytest.ini +0 -6
  131. django_cfg/modules/django_app_agent/services/__init__.py +0 -42
  132. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
  133. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
  134. django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
  135. django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
  136. django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
  137. django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
  138. django_cfg/modules/django_app_agent/services/base.py +0 -437
  139. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
  140. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
  141. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
  142. django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
  143. django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
  144. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
  145. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
  146. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
  147. django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
  148. django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
  149. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
  150. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
  151. django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
  152. django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
  153. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
  154. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
  155. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
  156. django_cfg/modules/django_app_agent/services/report_service.py +0 -332
  157. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
  158. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
  159. django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
  160. django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
  161. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
  162. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
  163. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
  164. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
  165. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
  166. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
  167. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
  168. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
  169. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
  170. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
  171. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
  172. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
  173. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
  174. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
  175. django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
  176. django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
  177. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
  178. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
  179. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
  180. django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
  181. django_cfg/modules/django_app_agent/ui/cli.py +0 -419
  182. django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
  183. django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
  184. django_cfg/modules/django_app_agent/utils/logging.py +0 -360
  185. django_cfg/modules/django_app_agent/utils/validation.py +0 -417
  186. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/WHEEL +0 -0
  187. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/entry_points.txt +0 -0
  188. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/licenses/LICENSE +0 -0
@@ -1,622 +0,0 @@
1
- """
2
- Rich UI Components for Django App Agent Module.
3
-
4
- This module provides beautiful terminal UI components using Rich library
5
- for progress tracking, question interfaces, error display, and status updates.
6
- """
7
-
8
- from typing import Dict, List, Optional, Any, Generator, ContextManager
9
- from contextlib import contextmanager
10
- from datetime import datetime, timedelta
11
- import time
12
-
13
- from rich.console import Console
14
- from rich.panel import Panel
15
- from rich.progress import (
16
- Progress, SpinnerColumn, TextColumn, BarColumn,
17
- TimeElapsedColumn, TimeRemainingColumn, MofNCompleteColumn
18
- )
19
- from rich.prompt import Prompt, Confirm, IntPrompt
20
- from rich.syntax import Syntax
21
- from rich.table import Table
22
- from rich.tree import Tree
23
- from rich.layout import Layout
24
- from rich.live import Live
25
- from rich.text import Text
26
- from rich.align import Align
27
- from rich.columns import Columns
28
- from rich.status import Status
29
-
30
- from ..models.requests import AppGenerationRequest
31
- from ..models.responses import AppGenerationResult
32
- from ..models.enums import AppType, AppComplexity, AppFeature
33
-
34
-
35
- class RichTheme:
36
- """Consistent color theme for Rich UI components."""
37
-
38
- PRIMARY = "bright_blue"
39
- SECONDARY = "bright_green"
40
- ACCENT = "bright_yellow"
41
- SUCCESS = "bright_green"
42
- WARNING = "bright_yellow"
43
- ERROR = "bright_red"
44
- INFO = "bright_cyan"
45
- MUTED = "dim white"
46
- CODE = "bright_magenta"
47
-
48
-
49
- class RichProgressTracker:
50
- """Rich progress tracking for long-running operations."""
51
-
52
- def __init__(self, console: Console):
53
- """Initialize progress tracker."""
54
- self.console = console
55
- self.theme = RichTheme()
56
-
57
- @contextmanager
58
- def track_generation(self, app_name: str) -> ContextManager['GenerationProgress']:
59
- """Track application generation progress."""
60
- progress = GenerationProgress(self.console, app_name)
61
- try:
62
- yield progress
63
- finally:
64
- progress.complete()
65
-
66
- @contextmanager
67
- def track_scanning(self) -> ContextManager['ScanningProgress']:
68
- """Track project scanning progress."""
69
- progress = ScanningProgress(self.console)
70
- try:
71
- yield progress
72
- finally:
73
- progress.complete()
74
-
75
-
76
- class GenerationProgress:
77
- """Progress tracker for application generation."""
78
-
79
- def __init__(self, console: Console, app_name: str):
80
- """Initialize generation progress."""
81
- self.console = console
82
- self.app_name = app_name
83
- self.start_time = datetime.now()
84
-
85
- # Create progress components
86
- self.progress = Progress(
87
- SpinnerColumn(),
88
- TextColumn("[progress.description]{task.description}"),
89
- BarColumn(),
90
- MofNCompleteColumn(),
91
- TimeElapsedColumn(),
92
- TimeRemainingColumn(),
93
- console=console,
94
- transient=False
95
- )
96
-
97
- # Define generation phases
98
- self.phases = [
99
- "🔍 Analyzing project structure",
100
- "🧠 Building development context",
101
- "❓ Processing requirements",
102
- "📋 Creating app manifest",
103
- "🏗️ Generating code files",
104
- "✅ Validating code quality",
105
- "📊 Calculating metrics",
106
- "📄 Creating documentation"
107
- ]
108
-
109
- self.current_phase = 0
110
- self.task_id = None
111
-
112
- def start(self):
113
- """Start progress tracking."""
114
- self.progress.start()
115
- self.task_id = self.progress.add_task(
116
- f"Generating {self.app_name}...",
117
- total=len(self.phases)
118
- )
119
-
120
- # Show initial phase
121
- self.update_phase(0)
122
-
123
- def update_phase(self, phase_index: int, message: Optional[str] = None):
124
- """Update current phase."""
125
- if phase_index < len(self.phases):
126
- self.current_phase = phase_index
127
- description = message or self.phases[phase_index]
128
-
129
- self.progress.update(
130
- self.task_id,
131
- description=description,
132
- completed=phase_index
133
- )
134
-
135
- def next_phase(self, message: Optional[str] = None):
136
- """Move to next phase."""
137
- self.update_phase(self.current_phase + 1, message)
138
-
139
- def complete(self):
140
- """Complete progress tracking."""
141
- if self.task_id:
142
- self.progress.update(
143
- self.task_id,
144
- description="✅ Generation completed!",
145
- completed=len(self.phases)
146
- )
147
-
148
- self.progress.stop()
149
-
150
- # Show completion summary
151
- duration = datetime.now() - self.start_time
152
- self._show_completion_summary(duration)
153
-
154
- def _show_completion_summary(self, duration: timedelta):
155
- """Show completion summary."""
156
- summary_text = Text()
157
- summary_text.append("🎉 Application generation completed!\n", style="bold green")
158
- summary_text.append(f"⏱️ Total time: {duration.total_seconds():.1f} seconds\n", style="cyan")
159
- summary_text.append(f"📱 App: {self.app_name}", style="blue")
160
-
161
- panel = Panel(
162
- summary_text,
163
- title="Generation Complete",
164
- border_style="green",
165
- padding=(1, 2)
166
- )
167
-
168
- self.console.print(panel)
169
-
170
-
171
- class ScanningProgress:
172
- """Progress tracker for project scanning."""
173
-
174
- def __init__(self, console: Console):
175
- """Initialize scanning progress."""
176
- self.console = console
177
- self.status = Status("🔍 Scanning project...", console=console)
178
-
179
- def start(self):
180
- """Start scanning progress."""
181
- self.status.start()
182
-
183
- def update(self, message: str):
184
- """Update scanning status."""
185
- self.status.update(f"🔍 {message}")
186
-
187
- def complete(self):
188
- """Complete scanning."""
189
- self.status.stop()
190
-
191
-
192
- class RichQuestionInterface:
193
- """Rich interface for interactive questioning."""
194
-
195
- def __init__(self, console: Console):
196
- """Initialize question interface."""
197
- self.console = console
198
- self.theme = RichTheme()
199
-
200
- def ask_app_details(self) -> Dict[str, Any]:
201
- """Ask for basic application details."""
202
- self.console.print()
203
- self._show_header("Application Details", "Let's gather some basic information about your app")
204
-
205
- # App name
206
- app_name = self._ask_app_name()
207
-
208
- # Description
209
- description = self._ask_description()
210
-
211
- # App type
212
- app_type = self._ask_app_type()
213
-
214
- # Complexity
215
- complexity = self._ask_complexity()
216
-
217
- return {
218
- "app_name": app_name,
219
- "description": description,
220
- "app_type": app_type,
221
- "complexity": complexity
222
- }
223
-
224
- def ask_features(self, complexity: AppComplexity) -> List[AppFeature]:
225
- """Ask for feature selection."""
226
- self._show_header("Feature Selection", f"Select features for your {complexity.value} application")
227
-
228
- recommended = complexity.get_recommended_features()
229
- all_features = list(AppFeature)
230
-
231
- # Show recommended features
232
- self._show_recommended_features(recommended)
233
-
234
- # Ask if user wants to customize
235
- if Confirm.ask("\n[bold]Customize feature selection?[/bold]", default=False):
236
- return self._customize_features(all_features, recommended)
237
- else:
238
- return list(recommended)
239
-
240
- def ask_contextual_questions(self, questions: List[Dict[str, Any]]) -> Dict[str, Any]:
241
- """Ask contextual questions based on project analysis."""
242
- self._show_header("Contextual Questions", "Based on your project, we have some specific questions")
243
-
244
- answers = {}
245
-
246
- for i, question in enumerate(questions, 1):
247
- self.console.print(f"\n[bold cyan]Question {i}/{len(questions)}:[/bold cyan]")
248
-
249
- # Show question context if available
250
- if question.get("context"):
251
- self._show_question_context(question["context"])
252
-
253
- # Ask the question
254
- answer = self._ask_question(question)
255
- answers[question["id"]] = answer
256
-
257
- # Show progress
258
- progress_bar = "█" * (i * 20 // len(questions)) + "░" * (20 - (i * 20 // len(questions)))
259
- self.console.print(f"[dim]Progress: [{progress_bar}] {i}/{len(questions)}[/dim]")
260
-
261
- return answers
262
-
263
- def _show_header(self, title: str, subtitle: str = ""):
264
- """Show section header."""
265
- header_text = Text()
266
- header_text.append(title, style=f"bold {self.theme.PRIMARY}")
267
- if subtitle:
268
- header_text.append(f"\n{subtitle}", style=self.theme.MUTED)
269
-
270
- panel = Panel(
271
- header_text,
272
- border_style=self.theme.PRIMARY,
273
- padding=(1, 2)
274
- )
275
-
276
- self.console.print(panel)
277
-
278
- def _ask_app_name(self) -> str:
279
- """Ask for application name."""
280
- while True:
281
- app_name = Prompt.ask(
282
- "[bold]Application name[/bold]",
283
- default="my_app"
284
- )
285
-
286
- # Basic validation
287
- if app_name.replace("_", "").isalnum() and app_name[0].isalpha():
288
- return app_name
289
- else:
290
- self.console.print("[red]❌ Invalid name. Use letters, numbers, and underscores only.[/red]")
291
-
292
- def _ask_description(self) -> str:
293
- """Ask for application description."""
294
- return Prompt.ask(
295
- "[bold]Brief description[/bold]",
296
- default="A Django application"
297
- )
298
-
299
- def _ask_app_type(self) -> AppType:
300
- """Ask for application type."""
301
- self.console.print("\n[bold]Application Type:[/bold]")
302
-
303
- table = Table(show_header=False, box=None, padding=(0, 2))
304
- table.add_column("Option", style="cyan")
305
- table.add_column("Description")
306
-
307
- table.add_row("1", "🐍 Django - Standard Django application")
308
- table.add_row("2", "⚙️ Django-CFG - Enhanced with configuration management")
309
-
310
- self.console.print(table)
311
-
312
- choice = Prompt.ask("Choose type", choices=["1", "2"], default="2")
313
- return AppType.DJANGO if choice == "1" else AppType.DJANGO_CFG
314
-
315
- def _ask_complexity(self) -> AppComplexity:
316
- """Ask for complexity level."""
317
- self.console.print("\n[bold]Complexity Level:[/bold]")
318
-
319
- table = Table(show_header=True, header_style="bold magenta")
320
- table.add_column("Option", style="cyan", width=8)
321
- table.add_column("Level", style="green")
322
- table.add_column("Description")
323
- table.add_column("Time", style="yellow")
324
-
325
- table.add_row("1", "Basic", "Simple app with core features", "~5 min")
326
- table.add_row("2", "Moderate", "Standard app with common features", "~15 min")
327
- table.add_row("3", "Advanced", "Complex app with advanced features", "~30 min")
328
- table.add_row("4", "Enterprise", "Full-featured enterprise app", "~60 min")
329
-
330
- self.console.print(table)
331
-
332
- choice = Prompt.ask("Choose complexity", choices=["1", "2", "3", "4"], default="2")
333
-
334
- complexity_map = {
335
- "1": AppComplexity.SIMPLE,
336
- "2": AppComplexity.MODERATE,
337
- "3": AppComplexity.ADVANCED,
338
- "4": AppComplexity.ENTERPRISE
339
- }
340
-
341
- return complexity_map[choice]
342
-
343
- def _show_recommended_features(self, features: set):
344
- """Show recommended features."""
345
- self.console.print("\n[bold green]Recommended Features:[/bold green]")
346
-
347
- columns = []
348
- for feature in sorted(features, key=lambda x: x.value):
349
- feature_text = Text()
350
- feature_text.append("✓ ", style="green")
351
- feature_text.append(feature.value.replace("_", " ").title(), style="white")
352
- columns.append(Panel(feature_text, padding=(0, 1), border_style="dim"))
353
-
354
- self.console.print(Columns(columns, equal=True, expand=True))
355
-
356
- def _customize_features(self, all_features: List[AppFeature], recommended: set) -> List[AppFeature]:
357
- """Allow feature customization."""
358
- selected = recommended.copy()
359
-
360
- self.console.print("\n[bold]Feature Customization:[/bold]")
361
- self.console.print("[dim]Type feature name to toggle, 'done' to finish[/dim]")
362
-
363
- while True:
364
- # Show current selection in columns
365
- self._show_feature_grid(all_features, selected)
366
-
367
- choice = Prompt.ask(
368
- "\nFeature to toggle (or 'done')",
369
- default="done"
370
- ).lower()
371
-
372
- if choice == "done":
373
- break
374
-
375
- # Find matching feature
376
- matching_feature = self._find_feature(choice, all_features)
377
-
378
- if matching_feature:
379
- if matching_feature in selected:
380
- selected.remove(matching_feature)
381
- self.console.print(f"[red]➖ Removed {matching_feature.value}[/red]")
382
- else:
383
- selected.add(matching_feature)
384
- self.console.print(f"[green]➕ Added {matching_feature.value}[/green]")
385
- else:
386
- self.console.print(f"[red]❌ Feature '{choice}' not found[/red]")
387
-
388
- return list(selected)
389
-
390
- def _show_feature_grid(self, all_features: List[AppFeature], selected: set):
391
- """Show features in a grid layout."""
392
- table = Table(show_header=True, header_style="bold magenta")
393
- table.add_column("Feature", style="white")
394
- table.add_column("Status", width=8, style="center")
395
- table.add_column("Description", style="dim")
396
-
397
- for feature in all_features:
398
- status = "✓" if feature in selected else " "
399
- status_style = "green" if feature in selected else "dim"
400
- description = self._get_feature_description(feature)
401
-
402
- table.add_row(
403
- feature.value.replace("_", " ").title(),
404
- status,
405
- description,
406
- style=status_style
407
- )
408
-
409
- self.console.print(table)
410
-
411
- def _find_feature(self, search: str, features: List[AppFeature]) -> Optional[AppFeature]:
412
- """Find feature by partial name match."""
413
- search = search.lower()
414
-
415
- # Exact match first
416
- for feature in features:
417
- if feature.value.lower() == search:
418
- return feature
419
-
420
- # Partial match
421
- for feature in features:
422
- if search in feature.value.lower():
423
- return feature
424
-
425
- return None
426
-
427
- def _get_feature_description(self, feature: AppFeature) -> str:
428
- """Get feature description."""
429
- descriptions = {
430
- AppFeature.MODELS: "Database models and ORM",
431
- AppFeature.VIEWS: "View functions and classes",
432
- AppFeature.URLS: "URL routing configuration",
433
- AppFeature.ADMIN: "Django admin interface",
434
- AppFeature.FORMS: "Form classes and validation",
435
- AppFeature.TEMPLATES: "HTML templates",
436
- AppFeature.API: "REST API with DRF",
437
- AppFeature.TESTS: "Unit and integration tests",
438
- AppFeature.TASKS: "Background tasks",
439
- AppFeature.DOCS: "Documentation",
440
- AppFeature.CONFIG: "Configuration management",
441
- AppFeature.SECURITY: "Security and permissions",
442
- }
443
- return descriptions.get(feature, "Additional feature")
444
-
445
- def _show_question_context(self, context: Dict[str, Any]):
446
- """Show context for a question."""
447
- if context.get("code_snippet"):
448
- code_panel = Panel(
449
- Syntax(context["code_snippet"], "python", theme="monokai"),
450
- title="📄 Relevant Code",
451
- border_style="dim"
452
- )
453
- self.console.print(code_panel)
454
-
455
- if context.get("explanation"):
456
- self.console.print(f"[dim]{context['explanation']}[/dim]")
457
-
458
- def _ask_question(self, question: Dict[str, Any]) -> Any:
459
- """Ask a single question."""
460
- question_type = question.get("type", "text")
461
-
462
- if question_type == "yes_no":
463
- return Confirm.ask(question["text"], default=question.get("default", True))
464
-
465
- elif question_type == "choice":
466
- choices = question.get("choices", [])
467
- if choices:
468
- self.console.print(f"\n[bold]{question['text']}[/bold]")
469
- for i, choice in enumerate(choices, 1):
470
- self.console.print(f" {i}. {choice}")
471
-
472
- choice_num = IntPrompt.ask(
473
- "Choose option",
474
- choices=[str(i) for i in range(1, len(choices) + 1)],
475
- default="1"
476
- )
477
- return choices[int(choice_num) - 1]
478
-
479
- else: # text
480
- return Prompt.ask(question["text"], default=question.get("default", ""))
481
-
482
-
483
- class RichErrorDisplay:
484
- """Rich error display with helpful suggestions."""
485
-
486
- def __init__(self, console: Console):
487
- """Initialize error display."""
488
- self.console = console
489
- self.theme = RichTheme()
490
-
491
- def show_error(
492
- self,
493
- title: str,
494
- message: str,
495
- errors: Optional[List[str]] = None,
496
- warnings: Optional[List[str]] = None,
497
- suggestions: Optional[List[str]] = None
498
- ):
499
- """Show comprehensive error information."""
500
- # Main error panel
501
- error_text = Text()
502
- error_text.append("❌ ", style=self.theme.ERROR)
503
- error_text.append(message, style="white")
504
-
505
- error_panel = Panel(
506
- error_text,
507
- title=f"[bold red]{title}[/bold red]",
508
- border_style=self.theme.ERROR,
509
- padding=(1, 2)
510
- )
511
-
512
- self.console.print(error_panel)
513
-
514
- # Show detailed errors
515
- if errors:
516
- self._show_error_list("Errors", errors, self.theme.ERROR)
517
-
518
- # Show warnings
519
- if warnings:
520
- self._show_error_list("Warnings", warnings, self.theme.WARNING)
521
-
522
- # Show suggestions
523
- if suggestions:
524
- self._show_suggestions(suggestions)
525
-
526
- def _show_error_list(self, title: str, items: List[str], style: str):
527
- """Show list of errors or warnings."""
528
- self.console.print(f"\n[bold {style}]{title}:[/bold {style}]")
529
-
530
- for item in items:
531
- self.console.print(f" • {item}", style=style)
532
-
533
- def _show_suggestions(self, suggestions: List[str]):
534
- """Show helpful suggestions."""
535
- self.console.print(f"\n[bold {self.theme.INFO}]💡 Suggestions:[/bold {self.theme.INFO}]")
536
-
537
- for suggestion in suggestions:
538
- self.console.print(f" • {suggestion}", style=self.theme.INFO)
539
-
540
-
541
- class RichStatusDisplay:
542
- """Rich status display for various operations."""
543
-
544
- def __init__(self, console: Console):
545
- """Initialize status display."""
546
- self.console = console
547
- self.theme = RichTheme()
548
-
549
- def show_generation_result(self, result: AppGenerationResult):
550
- """Show application generation result."""
551
- if result.status == "success":
552
- self._show_success_result(result)
553
- else:
554
- self._show_failure_result(result)
555
-
556
- def _show_success_result(self, result: AppGenerationResult):
557
- """Show successful generation result."""
558
- # Success header
559
- success_text = Text()
560
- success_text.append("🎉 Success! ", style="bold green")
561
- success_text.append(f"Generated '{result.app_name}' application", style="white")
562
-
563
- header_panel = Panel(
564
- success_text,
565
- border_style="green",
566
- padding=(1, 2)
567
- )
568
-
569
- self.console.print(header_panel)
570
-
571
- # Statistics table
572
- stats_table = Table(title="Generation Statistics", show_header=True)
573
- stats_table.add_column("Metric", style="cyan")
574
- stats_table.add_column("Value", style="green")
575
-
576
- stats_table.add_row("Files Generated", str(len(result.generated_files)))
577
- stats_table.add_row("Duration", f"{result.duration_seconds:.1f} seconds")
578
-
579
- if result.quality_metrics:
580
- stats_table.add_row("Code Quality", f"{result.quality_metrics.code_readability_score:.2f}/1.0")
581
- stats_table.add_row("Test Coverage", f"{result.quality_metrics.test_coverage_percentage:.1f}%")
582
-
583
- self.console.print(stats_table)
584
-
585
- # Next steps
586
- self._show_next_steps(result.app_name)
587
-
588
- def _show_failure_result(self, result: AppGenerationResult):
589
- """Show failed generation result."""
590
- error_text = Text()
591
- error_text.append("❌ Generation Failed\n", style="bold red")
592
- error_text.append(result.message, style="white")
593
-
594
- error_panel = Panel(
595
- error_text,
596
- border_style="red",
597
- padding=(1, 2)
598
- )
599
-
600
- self.console.print(error_panel)
601
-
602
- # Show errors if any
603
- if result.errors:
604
- self.console.print("\n[bold red]Errors:[/bold red]")
605
- for error in result.errors:
606
- self.console.print(f" • {error}", style="red")
607
-
608
- def _show_next_steps(self, app_name: str):
609
- """Show next steps after successful generation."""
610
- self.console.print("\n[bold]🚀 Next Steps:[/bold]")
611
-
612
- steps = [
613
- f"1. Add '{app_name}' to your INSTALLED_APPS",
614
- "2. Run migrations: [cyan]python manage.py makemigrations && python manage.py migrate[/cyan]",
615
- "3. Include URLs in your main urls.py",
616
- "4. Start development! 🎯"
617
- ]
618
-
619
- for step in steps:
620
- self.console.print(f" {step}")
621
-
622
- self.console.print()
@@ -1,38 +0,0 @@
1
- """
2
- Utility functions and helpers for Django App Agent Module.
3
-
4
- This module contains common utilities including:
5
- - Structured logging
6
- - Validation helpers
7
- - File system utilities
8
- - String processing functions
9
- """
10
-
11
- from .logging import (
12
- get_logger,
13
- setup_logging,
14
- log_execution_time,
15
- log_agent_operation,
16
- StructuredLogger,
17
- )
18
- from .validation import (
19
- validate_app_name,
20
- validate_file_path,
21
- validate_python_identifier,
22
- sanitize_filename,
23
- )
24
-
25
- __all__ = [
26
- # Logging
27
- "get_logger",
28
- "setup_logging",
29
- "log_execution_time",
30
- "log_agent_operation",
31
- "StructuredLogger",
32
-
33
- # Validation
34
- "validate_app_name",
35
- "validate_file_path",
36
- "validate_python_identifier",
37
- "sanitize_filename",
38
- ]