django-cfg 1.4.10__py3-none-any.whl → 1.4.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 (225) 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 +73 -49
  17. django_cfg/core/integration/display/startup.py +30 -22
  18. django_cfg/core/integration/url_integration.py +15 -16
  19. django_cfg/management/commands/check_endpoints.py +11 -160
  20. django_cfg/management/commands/check_settings.py +13 -348
  21. django_cfg/management/commands/clear_constance.py +13 -201
  22. django_cfg/management/commands/create_token.py +13 -321
  23. django_cfg/management/commands/generate_clients.py +23 -0
  24. django_cfg/management/commands/list_urls.py +13 -306
  25. django_cfg/management/commands/migrate_all.py +13 -126
  26. django_cfg/management/commands/migrator.py +13 -396
  27. django_cfg/management/commands/rundramatiq.py +15 -247
  28. django_cfg/management/commands/rundramatiq_simulator.py +12 -429
  29. django_cfg/management/commands/runserver_ngrok.py +15 -160
  30. django_cfg/management/commands/script.py +12 -488
  31. django_cfg/management/commands/show_config.py +12 -215
  32. django_cfg/management/commands/show_urls.py +12 -342
  33. django_cfg/management/commands/superuser.py +15 -295
  34. django_cfg/management/commands/task_clear.py +14 -217
  35. django_cfg/management/commands/task_status.py +13 -248
  36. django_cfg/management/commands/test_email.py +15 -86
  37. django_cfg/management/commands/test_telegram.py +14 -61
  38. django_cfg/management/commands/test_twilio.py +15 -105
  39. django_cfg/management/commands/tree.py +13 -383
  40. django_cfg/management/commands/validate_openapi.py +10 -0
  41. django_cfg/middleware/README.md +1 -1
  42. django_cfg/middleware/user_activity.py +3 -3
  43. django_cfg/models/__init__.py +2 -2
  44. django_cfg/models/api/drf/spectacular.py +6 -6
  45. django_cfg/models/django/__init__.py +2 -2
  46. django_cfg/models/django/openapi.py +162 -0
  47. django_cfg/modules/django_admin/management/commands/check_endpoints.py +169 -0
  48. django_cfg/modules/django_admin/management/commands/check_settings.py +355 -0
  49. django_cfg/modules/django_admin/management/commands/clear_constance.py +208 -0
  50. django_cfg/modules/django_admin/management/commands/create_token.py +328 -0
  51. django_cfg/modules/django_admin/management/commands/list_urls.py +313 -0
  52. django_cfg/modules/django_admin/management/commands/migrate_all.py +133 -0
  53. django_cfg/modules/django_admin/management/commands/migrator.py +403 -0
  54. django_cfg/modules/django_admin/management/commands/script.py +496 -0
  55. django_cfg/modules/django_admin/management/commands/show_config.py +225 -0
  56. django_cfg/modules/django_admin/management/commands/show_urls.py +361 -0
  57. django_cfg/modules/django_admin/management/commands/superuser.py +302 -0
  58. django_cfg/modules/django_admin/management/commands/tree.py +390 -0
  59. django_cfg/modules/django_client/__init__.py +20 -0
  60. django_cfg/modules/django_client/apps.py +35 -0
  61. django_cfg/modules/django_client/core/__init__.py +56 -0
  62. django_cfg/modules/django_client/core/archive/__init__.py +11 -0
  63. django_cfg/modules/django_client/core/archive/manager.py +134 -0
  64. django_cfg/modules/django_client/core/cli/__init__.py +12 -0
  65. django_cfg/modules/django_client/core/cli/main.py +235 -0
  66. django_cfg/modules/django_client/core/config/__init__.py +18 -0
  67. django_cfg/modules/django_client/core/config/config.py +208 -0
  68. django_cfg/modules/django_client/core/config/group.py +101 -0
  69. django_cfg/modules/django_client/core/config/service.py +209 -0
  70. django_cfg/modules/django_client/core/generator/__init__.py +115 -0
  71. django_cfg/modules/django_client/core/generator/base.py +838 -0
  72. django_cfg/modules/django_client/core/generator/python/__init__.py +16 -0
  73. django_cfg/modules/django_client/core/generator/python/async_client_gen.py +174 -0
  74. django_cfg/modules/django_client/core/generator/python/files_generator.py +180 -0
  75. django_cfg/modules/django_client/core/generator/python/generator.py +182 -0
  76. django_cfg/modules/django_client/core/generator/python/models_generator.py +318 -0
  77. django_cfg/modules/django_client/core/generator/python/operations_generator.py +278 -0
  78. django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +102 -0
  79. django_cfg/modules/django_client/core/generator/python/templates/__init__.py.jinja +9 -0
  80. django_cfg/modules/django_client/core/generator/python/templates/api_wrapper.py.jinja +153 -0
  81. django_cfg/modules/django_client/core/generator/python/templates/app_init.py.jinja +6 -0
  82. django_cfg/modules/django_client/core/generator/python/templates/client/app_client.py.jinja +18 -0
  83. django_cfg/modules/django_client/core/generator/python/templates/client/flat_client.py.jinja +38 -0
  84. django_cfg/modules/django_client/core/generator/python/templates/client/main_client.py.jinja +68 -0
  85. django_cfg/modules/django_client/core/generator/python/templates/client/main_client_file.py.jinja +14 -0
  86. django_cfg/modules/django_client/core/generator/python/templates/client/operation_method.py.jinja +9 -0
  87. django_cfg/modules/django_client/core/generator/python/templates/client/sub_client.py.jinja +18 -0
  88. django_cfg/modules/django_client/core/generator/python/templates/client/sync_main_client.py.jinja +50 -0
  89. django_cfg/modules/django_client/core/generator/python/templates/client/sync_operation_method.py.jinja +9 -0
  90. django_cfg/modules/django_client/core/generator/python/templates/client/sync_sub_client.py.jinja +18 -0
  91. django_cfg/modules/django_client/core/generator/python/templates/client_file.py.jinja +13 -0
  92. django_cfg/modules/django_client/core/generator/python/templates/main_init.py.jinja +52 -0
  93. django_cfg/modules/django_client/core/generator/python/templates/models/app_models.py.jinja +17 -0
  94. django_cfg/modules/django_client/core/generator/python/templates/models/enum_class.py.jinja +17 -0
  95. django_cfg/modules/django_client/core/generator/python/templates/models/enums.py.jinja +8 -0
  96. django_cfg/modules/django_client/core/generator/python/templates/models/models.py.jinja +17 -0
  97. django_cfg/modules/django_client/core/generator/python/templates/models/schema_class.py.jinja +21 -0
  98. django_cfg/modules/django_client/core/generator/python/templates/pyproject.toml.jinja +55 -0
  99. django_cfg/modules/django_client/core/generator/python/templates/utils/logger.py.jinja +255 -0
  100. django_cfg/modules/django_client/core/generator/python/templates/utils/retry.py.jinja +271 -0
  101. django_cfg/modules/django_client/core/generator/python/templates/utils/schema.py.jinja +12 -0
  102. django_cfg/modules/django_client/core/generator/typescript/__init__.py +14 -0
  103. django_cfg/modules/django_client/core/generator/typescript/client_generator.py +165 -0
  104. django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +428 -0
  105. django_cfg/modules/django_client/core/generator/typescript/files_generator.py +207 -0
  106. django_cfg/modules/django_client/core/generator/typescript/generator.py +432 -0
  107. django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +536 -0
  108. django_cfg/modules/django_client/core/generator/typescript/models_generator.py +245 -0
  109. django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +298 -0
  110. django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +329 -0
  111. django_cfg/modules/django_client/core/generator/typescript/templates/api_instance.ts.jinja +131 -0
  112. django_cfg/modules/django_client/core/generator/typescript/templates/app_index.ts.jinja +2 -0
  113. django_cfg/modules/django_client/core/generator/typescript/templates/client/app_client.ts.jinja +18 -0
  114. django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +403 -0
  115. django_cfg/modules/django_client/core/generator/typescript/templates/client/flat_client.ts.jinja +109 -0
  116. django_cfg/modules/django_client/core/generator/typescript/templates/client/main_client_file.ts.jinja +10 -0
  117. django_cfg/modules/django_client/core/generator/typescript/templates/client/operation.ts.jinja +61 -0
  118. django_cfg/modules/django_client/core/generator/typescript/templates/client/sub_client.ts.jinja +15 -0
  119. django_cfg/modules/django_client/core/generator/typescript/templates/client_file.ts.jinja +9 -0
  120. django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/fetchers.ts.jinja +45 -0
  121. django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/index.ts.jinja +30 -0
  122. django_cfg/modules/django_client/core/generator/typescript/templates/index.ts.jinja +5 -0
  123. django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +268 -0
  124. django_cfg/modules/django_client/core/generator/typescript/templates/models/app_models.ts.jinja +8 -0
  125. django_cfg/modules/django_client/core/generator/typescript/templates/models/enums.ts.jinja +4 -0
  126. django_cfg/modules/django_client/core/generator/typescript/templates/models/models.ts.jinja +8 -0
  127. django_cfg/modules/django_client/core/generator/typescript/templates/package.json.jinja +52 -0
  128. django_cfg/modules/django_client/core/generator/typescript/templates/schemas/index.ts.jinja +21 -0
  129. django_cfg/modules/django_client/core/generator/typescript/templates/schemas/schema.ts.jinja +24 -0
  130. django_cfg/modules/django_client/core/generator/typescript/templates/tsconfig.json.jinja +20 -0
  131. django_cfg/modules/django_client/core/generator/typescript/templates/utils/errors.ts.jinja +116 -0
  132. django_cfg/modules/django_client/core/generator/typescript/templates/utils/http.ts.jinja +98 -0
  133. django_cfg/modules/django_client/core/generator/typescript/templates/utils/logger.ts.jinja +259 -0
  134. django_cfg/modules/django_client/core/generator/typescript/templates/utils/retry.ts.jinja +175 -0
  135. django_cfg/modules/django_client/core/generator/typescript/templates/utils/schema.ts.jinja +7 -0
  136. django_cfg/modules/django_client/core/generator/typescript/templates/utils/storage.ts.jinja +158 -0
  137. django_cfg/modules/django_client/core/groups/__init__.py +13 -0
  138. django_cfg/modules/django_client/core/groups/detector.py +178 -0
  139. django_cfg/modules/django_client/core/groups/manager.py +314 -0
  140. django_cfg/modules/django_client/core/ir/__init__.py +57 -0
  141. django_cfg/modules/django_client/core/ir/context.py +387 -0
  142. django_cfg/modules/django_client/core/ir/operation.py +518 -0
  143. django_cfg/modules/django_client/core/ir/schema.py +353 -0
  144. django_cfg/modules/django_client/core/parser/__init__.py +74 -0
  145. django_cfg/modules/django_client/core/parser/base.py +648 -0
  146. django_cfg/modules/django_client/core/parser/models/__init__.py +74 -0
  147. django_cfg/modules/django_client/core/parser/models/base.py +212 -0
  148. django_cfg/modules/django_client/core/parser/models/components.py +160 -0
  149. django_cfg/modules/django_client/core/parser/models/openapi.py +203 -0
  150. django_cfg/modules/django_client/core/parser/models/operation.py +207 -0
  151. django_cfg/modules/django_client/core/parser/models/schema.py +266 -0
  152. django_cfg/modules/django_client/core/parser/openapi30.py +56 -0
  153. django_cfg/modules/django_client/core/parser/openapi31.py +64 -0
  154. django_cfg/modules/django_client/core/validation/__init__.py +22 -0
  155. django_cfg/modules/django_client/core/validation/checker.py +134 -0
  156. django_cfg/modules/django_client/core/validation/fixer.py +216 -0
  157. django_cfg/modules/django_client/core/validation/reporter.py +480 -0
  158. django_cfg/modules/django_client/core/validation/rules/__init__.py +11 -0
  159. django_cfg/modules/django_client/core/validation/rules/base.py +96 -0
  160. django_cfg/modules/django_client/core/validation/rules/type_hints.py +288 -0
  161. django_cfg/modules/django_client/core/validation/safety.py +266 -0
  162. django_cfg/modules/django_client/management/__init__.py +3 -0
  163. django_cfg/modules/django_client/management/commands/__init__.py +3 -0
  164. django_cfg/modules/django_client/management/commands/generate_client.py +427 -0
  165. django_cfg/modules/django_client/management/commands/validate_openapi.py +343 -0
  166. django_cfg/modules/django_client/pytest.ini +30 -0
  167. django_cfg/modules/django_client/spectacular/__init__.py +10 -0
  168. django_cfg/modules/django_client/spectacular/async_detection.py +187 -0
  169. django_cfg/modules/django_client/spectacular/enum_naming.py +192 -0
  170. django_cfg/modules/django_client/urls.py +72 -0
  171. django_cfg/{dashboard → modules/django_dashboard}/DEBUG_README.md +2 -2
  172. django_cfg/{dashboard → modules/django_dashboard}/REFACTORING_SUMMARY.md +1 -1
  173. django_cfg/modules/django_dashboard/management/__init__.py +0 -0
  174. django_cfg/modules/django_dashboard/management/commands/__init__.py +0 -0
  175. django_cfg/{dashboard → modules/django_dashboard}/management/commands/debug_dashboard.py +5 -5
  176. django_cfg/modules/django_dashboard/sections/documentation.py +391 -0
  177. django_cfg/modules/django_email/management/__init__.py +0 -0
  178. django_cfg/modules/django_email/management/commands/__init__.py +0 -0
  179. django_cfg/modules/django_email/management/commands/test_email.py +93 -0
  180. django_cfg/modules/django_logging/LOGGING_GUIDE.md +1 -1
  181. django_cfg/modules/django_logging/django_logger.py +6 -6
  182. django_cfg/modules/django_ngrok/management/__init__.py +0 -0
  183. django_cfg/modules/django_ngrok/management/commands/__init__.py +0 -0
  184. django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +167 -0
  185. django_cfg/modules/django_tasks/management/__init__.py +0 -0
  186. django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
  187. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +254 -0
  188. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +437 -0
  189. django_cfg/modules/django_tasks/management/commands/task_clear.py +226 -0
  190. django_cfg/modules/django_tasks/management/commands/task_status.py +257 -0
  191. django_cfg/modules/django_telegram/management/__init__.py +0 -0
  192. django_cfg/modules/django_telegram/management/commands/__init__.py +0 -0
  193. django_cfg/modules/django_telegram/management/commands/test_telegram.py +68 -0
  194. django_cfg/modules/django_twilio/management/__init__.py +0 -0
  195. django_cfg/modules/django_twilio/management/commands/__init__.py +0 -0
  196. django_cfg/modules/django_twilio/management/commands/test_twilio.py +112 -0
  197. django_cfg/modules/django_unfold/callbacks/main.py +21 -10
  198. django_cfg/modules/django_unfold/callbacks/revolution.py +41 -36
  199. django_cfg/pyproject.toml +2 -6
  200. django_cfg/registry/third_party.py +5 -7
  201. django_cfg/routing/callbacks.py +1 -1
  202. django_cfg/static/admin/css/prose-unfold.css +666 -0
  203. django_cfg/templates/admin/index.html +8 -0
  204. django_cfg/templates/admin/index_new.html +13 -0
  205. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +15 -3
  206. django_cfg/templates/admin/sections/documentation_section.html +172 -0
  207. django_cfg/templates/admin/snippets/tabs/documentation_tab.html +231 -0
  208. {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/METADATA +2 -2
  209. {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/RECORD +224 -74
  210. django_cfg/management/commands/generate.py +0 -107
  211. /django_cfg/models/django/{revolution.py → revolution_legacy.py} +0 -0
  212. /django_cfg/{dashboard → modules/django_admin}/management/__init__.py +0 -0
  213. /django_cfg/{dashboard → modules/django_admin}/management/commands/__init__.py +0 -0
  214. /django_cfg/{dashboard → modules/django_dashboard}/__init__.py +0 -0
  215. /django_cfg/{dashboard → modules/django_dashboard}/components.py +0 -0
  216. /django_cfg/{dashboard → modules/django_dashboard}/debug.py +0 -0
  217. /django_cfg/{dashboard → modules/django_dashboard}/sections/__init__.py +0 -0
  218. /django_cfg/{dashboard → modules/django_dashboard}/sections/base.py +0 -0
  219. /django_cfg/{dashboard → modules/django_dashboard}/sections/commands.py +0 -0
  220. /django_cfg/{dashboard → modules/django_dashboard}/sections/overview.py +0 -0
  221. /django_cfg/{dashboard → modules/django_dashboard}/sections/stats.py +0 -0
  222. /django_cfg/{dashboard → modules/django_dashboard}/sections/system.py +0 -0
  223. {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/WHEEL +0 -0
  224. {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/entry_points.txt +0 -0
  225. {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/licenses/LICENSE +0 -0
@@ -1,313 +1,20 @@
1
1
  """
2
- Show URLs Command
2
+ Django-CFG wrapper for list_urls command.
3
3
 
4
- Display all available URLs in the Django project with Rich formatting.
5
- Useful for development and webhook configuration.
6
- """
7
-
8
- import re
9
- from django.core.management.base import BaseCommand
10
- from django.urls import get_resolver
11
- from django.conf import settings
12
- from django_cfg.modules.django_logging import get_logger
13
-
14
-
15
- # Rich imports for beautiful output
16
- from rich.console import Console
17
- from rich.panel import Panel
18
- from rich.text import Text
19
- from rich.table import Table
20
- from rich.align import Align
21
-
22
- from django_cfg.core.state import get_current_config
23
-
24
-
25
- logger = get_logger('list_urls')
26
-
27
- class Command(BaseCommand):
28
- """Command to display all available URLs in the project."""
29
-
30
- # Web execution metadata
31
- web_executable = True
32
- requires_input = False
33
- is_destructive = False
34
-
35
- help = "Display all available URLs with Rich formatting"
36
-
37
- def __init__(self, *args, **kwargs):
38
- super().__init__(*args, **kwargs)
39
- self.console = Console()
40
- self.config = None
41
-
42
- def add_arguments(self, parser):
43
- parser.add_argument(
44
- "--filter",
45
- type=str,
46
- help="Filter URLs containing this string",
47
- default=None
48
- )
49
- parser.add_argument(
50
- "--webhook",
51
- action="store_true",
52
- help="Show only webhook-related URLs"
53
- )
54
- parser.add_argument(
55
- "--api",
56
- action="store_true",
57
- help="Show only API URLs"
58
- )
59
- parser.add_argument(
60
- "--with-ngrok",
61
- action="store_true",
62
- help="Show ngrok URLs alongside local URLs"
63
- )
64
-
65
- def handle(self, *args, **options):
66
- logger.info("Starting list_urls command")
67
- filter_str = options["filter"]
68
- webhook_only = options["webhook"]
69
- api_only = options["api"]
70
- with_ngrok = options["with_ngrok"]
71
-
72
- # Show header
73
- self.show_header()
74
-
75
- # Load config
76
- self.load_config()
4
+ This is a simple alias for django_admin.management.commands.list_urls.
5
+ All logic is in django_admin module.
77
6
 
78
- # Get all URLs
79
- urls = self.get_all_urls()
80
-
81
- # Filter URLs
82
- if filter_str:
83
- urls = [url for url in urls if filter_str.lower() in url['pattern'].lower()]
84
-
85
- if webhook_only:
86
- urls = [url for url in urls if 'webhook' in url['pattern'].lower() or 'hook' in url['pattern'].lower()]
87
-
88
- if api_only:
89
- urls = [url for url in urls if '/api/' in url['pattern'] or url['pattern'].startswith('api/')]
90
-
91
- # Display URLs
92
- self.display_urls(urls, with_ngrok)
93
-
94
- # Show webhook info if requested
95
- if webhook_only or with_ngrok:
96
- self.show_webhook_info()
97
-
98
- def show_header(self):
99
- """Show beautiful header with Rich."""
100
- title = Text("Django URLs Overview", style="bold cyan")
101
- subtitle = Text("All available URLs in your project", style="dim")
102
-
103
- header_content = Align.center(
104
- Text.assemble(
105
- title, "\n",
106
- subtitle
107
- )
108
- )
109
-
110
- self.console.print()
111
- self.console.print(Panel(
112
- header_content,
113
- title="šŸ”— URL Inspector",
114
- border_style="bright_blue",
115
- padding=(1, 2)
116
- ))
117
-
118
- def load_config(self):
119
- """Load Django CFG configuration."""
120
- try:
121
- self.config = get_current_config()
122
- except Exception as e:
123
- self.console.print(f"[yellow]āš ļø Failed to load config: {e}[/yellow]")
124
- self.config = None
125
-
126
- def get_all_urls(self):
127
- """Extract all URLs from Django URL configuration."""
128
- urls = []
129
- resolver = get_resolver()
130
-
131
- def extract_urls(url_patterns, prefix=''):
132
- for pattern in url_patterns:
133
- if hasattr(pattern, 'url_patterns'):
134
- # This is an include() - recurse
135
- new_prefix = prefix + str(pattern.pattern)
136
- extract_urls(pattern.url_patterns, new_prefix)
137
- else:
138
- # This is a regular URL pattern
139
- full_pattern = prefix + str(pattern.pattern)
140
-
141
- # Clean up the pattern
142
- clean_pattern = re.sub(r'\^|\$', '', full_pattern)
143
- clean_pattern = re.sub(r'\\/', '/', clean_pattern)
144
-
145
- # Get view info
146
- view_name = getattr(pattern, 'name', None)
147
- view_func = getattr(pattern, 'callback', None)
148
-
149
- if view_func:
150
- if hasattr(view_func, 'view_class'):
151
- # Class-based view
152
- view_info = f"{view_func.view_class.__name__}"
153
- module = view_func.view_class.__module__
154
- elif hasattr(view_func, '__name__'):
155
- # Function-based view
156
- view_info = f"{view_func.__name__}()"
157
- module = getattr(view_func, '__module__', 'unknown')
158
- else:
159
- view_info = str(view_func)
160
- module = 'unknown'
161
- else:
162
- view_info = 'Unknown'
163
- module = 'unknown'
164
-
165
- urls.append({
166
- 'pattern': clean_pattern,
167
- 'name': view_name,
168
- 'view': view_info,
169
- 'module': module
170
- })
171
-
172
- extract_urls(resolver.url_patterns)
173
- return urls
174
-
175
- def display_urls(self, urls, with_ngrok=False):
176
- """Display URLs in a Rich table."""
177
- if not urls:
178
- self.console.print("[yellow]No URLs found matching the criteria.[/yellow]")
179
- return
180
-
181
- # Create table
182
- table = Table(title=f"šŸ”— Found {len(urls)} URLs", show_header=True, header_style="bold cyan")
183
- table.add_column("URL Pattern", style="cyan", width=40)
184
- table.add_column("Name", style="white", width=20)
185
- table.add_column("View", style="green", width=25)
186
-
187
- if with_ngrok:
188
- table.add_column("Ngrok URL", style="magenta", width=40)
189
-
190
- # Get base URLs
191
- base_url = self.get_base_url()
192
- ngrok_url = self.get_ngrok_url() if with_ngrok else None
193
-
194
- # Add rows
195
- for url in urls[:50]: # Limit to first 50 URLs
196
- pattern = url['pattern']
197
- name = url['name'] or '—'
198
- view = url['view']
199
-
200
- # Truncate long view names
201
- if len(view) > 23:
202
- view = view[:20] + "..."
203
-
204
- row = [pattern, name, view]
205
-
206
- if with_ngrok:
207
- if ngrok_url:
208
- full_ngrok_url = f"{ngrok_url.rstrip('/')}/{pattern.lstrip('/')}"
209
- row.append(full_ngrok_url)
210
- else:
211
- row.append("—")
212
-
213
- table.add_row(*row)
214
-
215
- if len(urls) > 50:
216
- table.caption = f"Showing first 50 of {len(urls)} URLs"
217
-
218
- self.console.print(table)
7
+ Usage:
8
+ python manage.py list_urls
9
+ """
219
10
 
220
- # Show base URL info
221
- info_table = Table(show_header=False, box=None)
222
- info_table.add_column("Info", style="cyan")
223
- info_table.add_column("Value", style="white")
224
-
225
- info_table.add_row("🌐 Base URL:", base_url)
226
- if with_ngrok and ngrok_url:
227
- info_table.add_row("šŸ”— Ngrok URL:", ngrok_url)
228
-
229
- self.console.print()
230
- self.console.print(info_table)
11
+ from django_cfg.modules.django_admin.management.commands.list_urls import Command as ListUrlsCommand
231
12
 
232
- def show_webhook_info(self):
233
- """Show webhook-specific information using reverse."""
234
- self.console.print()
235
-
236
- webhook_table = Table(title="šŸ”” Webhook Configuration", show_header=True, header_style="bold yellow")
237
- webhook_table.add_column("Service", style="white", width=25)
238
- webhook_table.add_column("Local URL", style="cyan", width=60)
239
- webhook_table.add_column("Ngrok URL", style="magenta", width=60)
240
-
241
- base_url = self.get_base_url()
242
- ngrok_url = self.get_ngrok_url()
243
-
244
- # Get webhook URLs using reverse
245
- try:
246
- from django.urls import reverse
247
-
248
- # Common webhook endpoints with their URL names
249
- webhooks = [
250
- ("Twilio Message Status", "cfg_accounts:webhook-message-status"),
251
- ("Twilio Verification", "cfg_accounts:webhook-verification-status"),
252
- ]
253
-
254
- for service, url_name in webhooks:
255
- try:
256
- # Get the reversed URL path
257
- url_path = reverse(url_name)
258
-
259
- # Build full URLs
260
- local_full = f"{base_url.rstrip('/')}{url_path}"
261
- ngrok_full = f"{ngrok_url.rstrip('/')}{url_path}" if ngrok_url else "—"
262
-
263
- webhook_table.add_row(service, local_full, ngrok_full)
264
-
265
- except Exception as e:
266
- # Fallback if reverse fails
267
- self.console.print(f"[yellow]āš ļø Could not reverse URL for {service}: {e}[/yellow]")
268
- fallback_path = f"/api/accounts/webhook/{service.lower().replace(' ', '-').replace('twilio ', '')}/"
269
- local_full = f"{base_url.rstrip('/')}{fallback_path}"
270
- ngrok_full = f"{ngrok_url.rstrip('/')}{fallback_path}" if ngrok_url else "—"
271
- webhook_table.add_row(service, local_full, ngrok_full)
272
-
273
- except ImportError:
274
- # Fallback if Django is not available
275
- webhooks = [
276
- ("Twilio Message Status", "/api/accounts/webhook/message-status/"),
277
- ("Twilio Verification", "/api/accounts/webhook/verification-status/"),
278
- ]
279
-
280
- for service, endpoint in webhooks:
281
- local_full = f"{base_url.rstrip('/')}{endpoint}"
282
- ngrok_full = f"{ngrok_url.rstrip('/')}{endpoint}" if ngrok_url else "—"
283
- webhook_table.add_row(service, local_full, ngrok_full)
284
-
285
- self.console.print(webhook_table)
286
-
287
- # Show tips
288
- tips = [
289
- "šŸ’” Use ngrok URLs for webhook configuration in production services",
290
- "šŸ”’ Always validate webhook signatures in production",
291
- "šŸ“ Test webhooks using the test_twilio management command",
292
- ]
293
-
294
- for tip in tips:
295
- self.console.print(f"[dim]{tip}[/dim]")
296
13
 
297
- def get_base_url(self):
298
- """Get base URL for the application."""
299
- if self.config:
300
- return self.config.api_url
301
- else:
302
- # Fallback to Django settings
303
- debug = getattr(settings, 'DEBUG', True)
304
- if debug:
305
- return "http://localhost:8000"
306
- else:
307
- return "https://yourdomain.com"
14
+ class Command(ListUrlsCommand):
15
+ """
16
+ Alias for list_urls command.
308
17
 
309
- def get_ngrok_url(self):
310
- """Get ngrok URL if available."""
311
- if self.config:
312
- return self.config.get_ngrok_url()
313
- return None
18
+ Simply inherits from ListUrlsCommand without any changes.
19
+ """
20
+ pass
@@ -1,133 +1,20 @@
1
1
  """
2
- Simple Migration Command for Django Config Toolkit
3
- Migrate all databases based on django-cfg configuration.
4
- """
5
-
6
- from django.core.management.base import BaseCommand
7
- from django.core.management import call_command
8
- from django.apps import apps
9
- from django_cfg.modules.django_logging import get_logger
10
-
11
-
12
- from django_cfg.core.state import get_current_config
13
-
14
-
15
- logger = get_logger('migrate_all')
2
+ Django-CFG wrapper for migrate_all command.
16
3
 
17
- class Command(BaseCommand):
18
- # Web execution metadata
19
- web_executable = False
20
- requires_input = False
21
- is_destructive = True
4
+ This is a simple alias for django_admin.management.commands.migrate_all.
5
+ All logic is in django_admin module.
22
6
 
23
- help = "Migrate all databases based on django-cfg configuration"
24
-
25
- def add_arguments(self, parser):
26
- parser.add_argument(
27
- "--dry-run",
28
- action="store_true",
29
- help="Show what would be migrated without executing"
30
- )
31
- parser.add_argument(
32
- "--skip-makemigrations",
33
- action="store_true",
34
- help="Skip makemigrations step"
35
- )
36
-
37
- def handle(self, *args, **options):
38
- """Run migrations for all configured databases."""
39
- logger.info("Starting migrate_all command")
40
- dry_run = options.get("dry_run", False)
41
- skip_makemigrations = options.get("skip_makemigrations", False)
42
-
43
- if dry_run:
44
- self.stdout.write(self.style.WARNING("šŸ” DRY RUN - No changes will be made"))
45
-
46
- self.stdout.write(self.style.SUCCESS("šŸš€ Migrating all databases..."))
47
-
48
- # Step 1: Create migrations if needed
49
- if not skip_makemigrations:
50
- self.stdout.write("šŸ“ Creating migrations...")
51
- if not dry_run:
52
- call_command("makemigrations", verbosity=1)
53
- else:
54
- self.stdout.write(" Would run: makemigrations")
55
-
56
- # Step 2: Get database configuration
57
- try:
58
- config = get_current_config()
59
- if not config or not hasattr(config, 'databases'):
60
- self.stdout.write(self.style.ERROR("āŒ No django-cfg configuration found"))
61
- return
62
- except Exception as e:
63
- self.stdout.write(self.style.ERROR(f"āŒ Error loading configuration: {e}"))
64
- return
7
+ Usage:
8
+ python manage.py migrate_all
9
+ """
65
10
 
66
- # Step 3: Migrate each database
67
- for db_name, db_config in config.databases.items():
68
- self.stdout.write(f"\nšŸ”„ Migrating database: {db_name}")
69
-
70
- if hasattr(db_config, 'apps') and db_config.apps:
71
- # Migrate specific apps for this database
72
- for app_path in db_config.apps:
73
- app_label = self._get_app_label(app_path)
74
- if app_label:
75
- self.stdout.write(f" šŸ“¦ Migrating {app_label}...")
76
- if not dry_run:
77
- try:
78
- call_command("migrate", app_label, database=db_name, verbosity=1)
79
- except Exception as e:
80
- self.stdout.write(self.style.ERROR(f" āŒ Migration failed for {app_label} on {db_name}: {e}"))
81
- logger.error(f"Migration failed for {app_label} on {db_name}: {e}")
82
- raise SystemExit(1)
83
- else:
84
- self.stdout.write(f" Would run: migrate {app_label} --database={db_name}")
85
- else:
86
- # Migrate all apps for this database (usually default)
87
- self.stdout.write(f" šŸ“¦ Migrating all apps...")
88
- if not dry_run:
89
- try:
90
- call_command("migrate", database=db_name, verbosity=1)
91
- except Exception as e:
92
- self.stdout.write(self.style.ERROR(f" āŒ Migration failed for all apps on {db_name}: {e}"))
93
- logger.error(f"Migration failed for all apps on {db_name}: {e}")
94
- raise SystemExit(1)
95
- else:
96
- self.stdout.write(f" Would run: migrate --database={db_name}")
11
+ from django_cfg.modules.django_admin.management.commands.migrate_all import Command as MigrateAllCommand
97
12
 
98
- # Step 4: Migrate constance if needed
99
- self.stdout.write(f"\nšŸ”§ Migrating constance...")
100
- if not dry_run:
101
- try:
102
- call_command("migrate", "constance", database="default", verbosity=1)
103
- except Exception as e:
104
- self.stdout.write(self.style.ERROR(f"āŒ Constance migration failed: {e}"))
105
- logger.error(f"Constance migration failed: {e}")
106
- raise SystemExit(1)
107
- else:
108
- self.stdout.write(" Would run: migrate constance --database=default")
109
13
 
110
- self.stdout.write(self.style.SUCCESS("\nāœ… All migrations completed!"))
14
+ class Command(MigrateAllCommand):
15
+ """
16
+ Alias for migrate_all command.
111
17
 
112
- def _get_app_label(self, app_path: str) -> str:
113
- """Convert full module path to Django app_label."""
114
- try:
115
- # Try to get app config by full path first
116
- try:
117
- app_config = apps.get_app_config(app_path)
118
- return app_config.label
119
- except LookupError:
120
- pass
121
-
122
- # Fallback: extract last part of the path as potential app_label
123
- potential_label = app_path.split('.')[-1]
124
- try:
125
- app_config = apps.get_app_config(potential_label)
126
- return app_config.label
127
- except LookupError:
128
- pass
129
-
130
- return app_path
131
-
132
- except Exception:
133
- return app_path
18
+ Simply inherits from MigrateAllCommand without any changes.
19
+ """
20
+ pass