django-cfg 1.3.11__py3-none-any.whl → 1.4.0__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 (439) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/accounts/admin/user_admin.py +39 -16
  4. django_cfg/apps/accounts/serializers/profile.py +1 -1
  5. django_cfg/apps/accounts/services/otp_service.py +18 -11
  6. django_cfg/apps/accounts/signals.py +15 -24
  7. django_cfg/apps/accounts/utils/notifications.py +217 -358
  8. django_cfg/apps/accounts/views/otp.py +2 -2
  9. django_cfg/apps/accounts/views/webhook.py +1 -1
  10. django_cfg/apps/agents/core/django_agent.py +1 -1
  11. django_cfg/apps/api/commands/views.py +66 -83
  12. django_cfg/apps/api/health/drf_views.py +269 -0
  13. django_cfg/apps/api/health/serializers.py +45 -0
  14. django_cfg/apps/api/health/urls.py +6 -1
  15. django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
  16. django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
  17. django_cfg/apps/knowbase/admin/document_admin.py +136 -270
  18. django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
  19. django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
  20. django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
  21. django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
  22. django_cfg/apps/knowbase/config/constance_fields.py +1 -1
  23. django_cfg/apps/knowbase/config/settings.py +2 -2
  24. django_cfg/apps/knowbase/mixins/__init__.py +19 -2
  25. django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
  26. django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
  27. django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
  28. django_cfg/apps/knowbase/mixins/creator.py +10 -10
  29. django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
  30. django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
  31. django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
  32. django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
  33. django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
  34. django_cfg/apps/knowbase/mixins/service.py +2 -2
  35. django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
  36. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
  37. django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
  38. django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
  39. django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
  40. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
  41. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
  42. django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
  43. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
  44. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
  45. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
  46. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
  47. django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
  48. django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
  49. django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
  50. django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
  51. django_cfg/apps/knowbase/services/embedding/models.py +18 -14
  52. django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
  53. django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
  54. django_cfg/apps/leads/tests.py +1 -1
  55. django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
  56. django_cfg/apps/payments/admin/balance_admin.py +1 -1
  57. django_cfg/apps/payments/admin/currencies_admin.py +1 -1
  58. django_cfg/apps/payments/admin/payments_admin.py +1 -1
  59. django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
  60. django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
  61. django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
  62. django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
  63. django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
  64. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
  65. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
  66. django_cfg/apps/payments/admin_interface/views/base.py +29 -2
  67. django_cfg/apps/payments/apps.py +1 -1
  68. django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
  69. django_cfg/apps/payments/config/helpers.py +3 -2
  70. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
  71. django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
  72. django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
  73. django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
  74. django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
  75. django_cfg/apps/payments/management/commands/test_providers.py +1 -1
  76. django_cfg/apps/payments/middleware/api_access.py +1 -1
  77. django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
  78. django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
  79. django_cfg/apps/payments/models/balance.py +2 -2
  80. django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
  81. django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
  82. django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
  83. django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
  84. django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
  85. django_cfg/apps/payments/models/payments.py +2 -2
  86. django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
  87. django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
  88. django_cfg/apps/payments/services/core/base.py +1 -1
  89. django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
  90. django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
  91. django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
  92. django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
  93. django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
  94. django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
  95. django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
  96. django_cfg/apps/payments/services/core/payment_service.py +124 -612
  97. django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
  98. django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
  99. django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
  100. django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
  101. django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
  102. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
  103. django_cfg/apps/payments/services/providers/base.py +1 -1
  104. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
  105. django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
  106. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
  107. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
  108. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
  109. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
  110. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
  111. django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
  112. django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
  113. django_cfg/apps/payments/services/providers/registry.py +1 -1
  114. django_cfg/apps/payments/services/providers/sync_service.py +1 -1
  115. django_cfg/apps/payments/signals/__init__.py +1 -1
  116. django_cfg/apps/payments/signals/api_key_signals.py +1 -1
  117. django_cfg/apps/payments/signals/balance_signals.py +1 -1
  118. django_cfg/apps/payments/signals/payment_signals.py +1 -1
  119. django_cfg/apps/payments/signals/subscription_signals.py +1 -1
  120. django_cfg/apps/payments/views/api/api_keys.py +1 -1
  121. django_cfg/apps/payments/views/api/balances.py +1 -1
  122. django_cfg/apps/payments/views/api/base.py +1 -1
  123. django_cfg/apps/payments/views/api/currencies.py +1 -1
  124. django_cfg/apps/payments/views/api/payments.py +1 -1
  125. django_cfg/apps/payments/views/api/subscriptions.py +1 -1
  126. django_cfg/apps/payments/views/api/webhooks.py +1 -1
  127. django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
  128. django_cfg/apps/payments/views/serializers/balances.py +1 -1
  129. django_cfg/apps/payments/views/serializers/currencies.py +1 -1
  130. django_cfg/apps/payments/views/serializers/payments.py +1 -1
  131. django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
  132. django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
  133. django_cfg/apps/support/admin/support_admin.py +21 -13
  134. django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
  135. django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
  136. django_cfg/apps/support/utils/support_email_service.py +1 -1
  137. django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
  138. django_cfg/apps/tasks/utils/simulator.py +1 -1
  139. django_cfg/apps/tasks/views/dashboard.py +33 -3
  140. django_cfg/apps/urls.py +5 -1
  141. django_cfg/cli/README.md +57 -471
  142. django_cfg/cli/commands/create_project.py +140 -529
  143. django_cfg/cli/main.py +13 -10
  144. django_cfg/core/__init__.py +63 -6
  145. django_cfg/core/base/__init__.py +5 -0
  146. django_cfg/core/base/config_model.py +652 -0
  147. django_cfg/core/builders/__init__.py +11 -0
  148. django_cfg/core/builders/apps_builder.py +258 -0
  149. django_cfg/core/builders/middleware_builder.py +115 -0
  150. django_cfg/core/builders/security_builder.py +96 -0
  151. django_cfg/core/config.py +20 -892
  152. django_cfg/core/constants.py +69 -0
  153. django_cfg/core/environment/__init__.py +9 -0
  154. django_cfg/core/exceptions.py +45 -298
  155. django_cfg/core/generation/__init__.py +51 -0
  156. django_cfg/core/generation/core_generators/__init__.py +0 -0
  157. django_cfg/core/generation/core_generators/settings.py +90 -0
  158. django_cfg/core/generation/core_generators/static.py +82 -0
  159. django_cfg/core/generation/core_generators/templates.py +141 -0
  160. django_cfg/core/generation/data_generators/__init__.py +15 -0
  161. django_cfg/core/generation/data_generators/cache.py +132 -0
  162. django_cfg/core/generation/data_generators/database.py +117 -0
  163. django_cfg/core/generation/generation.py +92 -0
  164. django_cfg/core/generation/integration_generators/__init__.py +21 -0
  165. django_cfg/core/generation/integration_generators/api.py +237 -0
  166. django_cfg/core/generation/integration_generators/sessions.py +65 -0
  167. django_cfg/core/generation/integration_generators/tailwind.py +54 -0
  168. django_cfg/core/generation/integration_generators/tasks.py +92 -0
  169. django_cfg/core/generation/integration_generators/third_party.py +144 -0
  170. django_cfg/core/generation/orchestrator.py +285 -0
  171. django_cfg/core/generation/protocols.py +30 -0
  172. django_cfg/core/generation/security_generators/__init__.py +0 -0
  173. django_cfg/core/generation/utility_generators/__init__.py +24 -0
  174. django_cfg/core/generation/utility_generators/email.py +58 -0
  175. django_cfg/core/generation/utility_generators/i18n.py +66 -0
  176. django_cfg/core/generation/utility_generators/limits.py +58 -0
  177. django_cfg/core/generation/utility_generators/logging.py +66 -0
  178. django_cfg/core/generation/utility_generators/security.py +101 -0
  179. django_cfg/core/generation/utils/__init__.py +0 -0
  180. django_cfg/core/generation/utils/helpers.py +32 -0
  181. django_cfg/core/integration/__init__.py +18 -25
  182. django_cfg/core/integration/display/startup.py +146 -133
  183. django_cfg/core/integration/url_integration.py +13 -2
  184. django_cfg/core/services/__init__.py +5 -0
  185. django_cfg/core/services/config_service.py +121 -0
  186. django_cfg/core/state/__init__.py +9 -0
  187. django_cfg/core/state/registry.py +84 -0
  188. django_cfg/core/types/__init__.py +15 -0
  189. django_cfg/core/types/aliases.py +15 -0
  190. django_cfg/core/types/enums.py +49 -0
  191. django_cfg/dashboard/DEBUG_README.md +105 -0
  192. django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
  193. django_cfg/dashboard/__init__.py +24 -0
  194. django_cfg/dashboard/components.py +308 -0
  195. django_cfg/dashboard/debug.py +176 -0
  196. django_cfg/dashboard/management/__init__.py +0 -0
  197. django_cfg/dashboard/management/commands/__init__.py +0 -0
  198. django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
  199. django_cfg/dashboard/sections/__init__.py +1 -0
  200. django_cfg/dashboard/sections/base.py +128 -0
  201. django_cfg/dashboard/sections/commands.py +32 -0
  202. django_cfg/dashboard/sections/overview.py +394 -0
  203. django_cfg/dashboard/sections/stats.py +48 -0
  204. django_cfg/dashboard/sections/system.py +73 -0
  205. django_cfg/management/commands/check_settings.py +6 -2
  206. django_cfg/management/commands/clear_constance.py +6 -1
  207. django_cfg/management/commands/create_token.py +5 -4
  208. django_cfg/management/commands/generate.py +5 -0
  209. django_cfg/management/commands/list_urls.py +7 -2
  210. django_cfg/management/commands/migrate_all.py +6 -2
  211. django_cfg/management/commands/migrator.py +6 -1
  212. django_cfg/management/commands/rundramatiq.py +6 -1
  213. django_cfg/management/commands/rundramatiq_simulator.py +11 -4
  214. django_cfg/management/commands/runserver_ngrok.py +9 -7
  215. django_cfg/management/commands/script.py +25 -21
  216. django_cfg/management/commands/show_config.py +6 -1
  217. django_cfg/management/commands/show_urls.py +8 -3
  218. django_cfg/management/commands/superuser.py +5 -4
  219. django_cfg/management/commands/task_clear.py +8 -3
  220. django_cfg/management/commands/task_status.py +8 -3
  221. django_cfg/management/commands/test_email.py +6 -1
  222. django_cfg/management/commands/test_telegram.py +6 -1
  223. django_cfg/management/commands/test_twilio.py +6 -1
  224. django_cfg/management/commands/tree.py +7 -4
  225. django_cfg/models/__init__.py +88 -3
  226. django_cfg/models/api/__init__.py +27 -0
  227. django_cfg/models/{api.py → api/config.py} +1 -1
  228. django_cfg/models/api/drf/__init__.py +21 -0
  229. django_cfg/models/api/drf/config.py +101 -0
  230. django_cfg/models/api/drf/redoc.py +31 -0
  231. django_cfg/models/api/drf/spectacular.py +129 -0
  232. django_cfg/models/api/drf/swagger.py +59 -0
  233. django_cfg/models/{api_keys.py → api/keys.py} +16 -6
  234. django_cfg/models/{limits.py → api/limits.py} +0 -1
  235. django_cfg/models/base/__init__.py +14 -0
  236. django_cfg/models/django/__init__.py +16 -0
  237. django_cfg/models/{constance.py → django/constance.py} +1 -1
  238. django_cfg/models/{environment.py → django/environment.py} +1 -1
  239. django_cfg/models/infrastructure/__init__.py +17 -0
  240. django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
  241. django_cfg/models/infrastructure/database/__init__.py +22 -0
  242. django_cfg/models/infrastructure/database/config.py +265 -0
  243. django_cfg/models/infrastructure/database/converters.py +91 -0
  244. django_cfg/models/infrastructure/database/parsers.py +96 -0
  245. django_cfg/models/infrastructure/database/routing.py +85 -0
  246. django_cfg/models/infrastructure/database/validators.py +170 -0
  247. django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
  248. django_cfg/models/{security.py → infrastructure/security.py} +2 -2
  249. django_cfg/models/ngrok/__init__.py +11 -0
  250. django_cfg/models/ngrok/auth.py +37 -0
  251. django_cfg/models/ngrok/config.py +77 -0
  252. django_cfg/models/ngrok/tunnel.py +35 -0
  253. django_cfg/models/payments/__init__.py +20 -0
  254. django_cfg/models/payments/api_keys.py +57 -0
  255. django_cfg/models/{payments.py → payments/config.py} +56 -154
  256. django_cfg/models/payments/providers/__init__.py +15 -0
  257. django_cfg/models/payments/providers/base.py +25 -0
  258. django_cfg/models/payments/providers/nowpayments.py +48 -0
  259. django_cfg/models/services/__init__.py +18 -0
  260. django_cfg/models/services/base.py +65 -0
  261. django_cfg/models/{email.py → services/email.py} +1 -1
  262. django_cfg/models/services/telegram.py +172 -0
  263. django_cfg/models/tasks/__init__.py +51 -0
  264. django_cfg/models/tasks/backends.py +250 -0
  265. django_cfg/models/tasks/config.py +314 -0
  266. django_cfg/models/tasks/utils.py +174 -0
  267. django_cfg/modules/base.py +18 -3
  268. django_cfg/modules/django_admin/decorators/actions.py +1 -1
  269. django_cfg/modules/django_admin/decorators/display.py +1 -1
  270. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
  271. django_cfg/modules/django_cfg_rpc_client/README.md +346 -0
  272. django_cfg/modules/django_cfg_rpc_client/__init__.py +51 -0
  273. django_cfg/modules/django_cfg_rpc_client/client.py +540 -0
  274. django_cfg/modules/django_cfg_rpc_client/config.py +207 -0
  275. django_cfg/modules/django_cfg_rpc_client/dashboard/README.md +517 -0
  276. django_cfg/modules/django_cfg_rpc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
  277. django_cfg/modules/django_cfg_rpc_client/dashboard/__init__.py +11 -0
  278. django_cfg/modules/django_cfg_rpc_client/dashboard/apps.py +22 -0
  279. django_cfg/modules/django_cfg_rpc_client/dashboard/monitor.py +435 -0
  280. django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js +373 -0
  281. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html +76 -0
  282. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html +200 -0
  283. django_cfg/modules/django_cfg_rpc_client/dashboard/urls.py +22 -0
  284. django_cfg/modules/django_cfg_rpc_client/dashboard/urls_admin.py +9 -0
  285. django_cfg/modules/django_cfg_rpc_client/dashboard/views.py +251 -0
  286. django_cfg/modules/django_cfg_rpc_client/exceptions.py +201 -0
  287. django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
  288. django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
  289. django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
  290. django_cfg/modules/django_drf_theme/README.md +207 -0
  291. django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
  292. django_cfg/modules/django_drf_theme/__init__.py +23 -0
  293. django_cfg/modules/django_drf_theme/apps.py +15 -0
  294. django_cfg/modules/django_drf_theme/renderers.py +58 -0
  295. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
  296. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
  297. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
  298. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
  299. django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
  300. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
  301. django_cfg/modules/django_email/__init__.py +14 -0
  302. django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
  303. django_cfg/modules/django_email/utils.py +40 -0
  304. django_cfg/modules/django_health/__init__.py +9 -0
  305. django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
  306. django_cfg/modules/django_llm/llm/client.py +155 -550
  307. django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
  308. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
  309. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
  310. django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
  311. django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
  312. django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
  313. django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
  314. django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
  315. django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
  316. django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
  317. django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
  318. django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
  319. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
  320. django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
  321. django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
  322. django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
  323. django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
  324. django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
  325. django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
  326. django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
  327. django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
  328. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
  329. django_cfg/modules/django_llm/translator/translator.py +150 -603
  330. django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
  331. django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
  332. django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
  333. django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
  334. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
  335. django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
  336. django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
  337. django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
  338. django_cfg/modules/django_logging/__init__.py +14 -0
  339. django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
  340. django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
  341. django_cfg/modules/django_ngrok/__init__.py +39 -0
  342. django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
  343. django_cfg/modules/django_rpc_old/POETRY.md +344 -0
  344. django_cfg/modules/django_rpc_old/README.md +397 -0
  345. django_cfg/modules/django_rpc_old/TESTING.md +358 -0
  346. django_cfg/modules/django_rpc_old/__init__.py +39 -0
  347. django_cfg/modules/django_rpc_old/client.py +531 -0
  348. django_cfg/modules/django_rpc_old/config.py +279 -0
  349. django_cfg/modules/django_rpc_old/exceptions.py +172 -0
  350. django_cfg/modules/django_tailwind/README.md +478 -0
  351. django_cfg/modules/django_tailwind/__init__.py +7 -0
  352. django_cfg/modules/django_tailwind/apps.py +10 -0
  353. django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
  354. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
  355. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
  356. django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
  357. django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
  358. django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
  359. django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
  360. django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
  361. django_cfg/modules/django_tasks/__init__.py +29 -0
  362. django_cfg/modules/django_tasks/factory.py +127 -0
  363. django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
  364. django_cfg/modules/django_tasks/settings.py +107 -0
  365. django_cfg/modules/django_telegram/__init__.py +29 -0
  366. django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
  367. django_cfg/modules/django_telegram/utils.py +62 -0
  368. django_cfg/modules/django_twilio/__init__.py +54 -107
  369. django_cfg/modules/django_twilio/_imports.py +30 -0
  370. django_cfg/modules/django_twilio/base.py +192 -0
  371. django_cfg/modules/django_twilio/email_otp.py +227 -0
  372. django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
  373. django_cfg/modules/django_twilio/simple_service.py +1 -2
  374. django_cfg/modules/django_twilio/sms.py +94 -0
  375. django_cfg/modules/django_twilio/twilio_service.py +2 -3
  376. django_cfg/modules/django_twilio/unified.py +310 -0
  377. django_cfg/modules/django_twilio/utils.py +190 -0
  378. django_cfg/modules/django_twilio/whatsapp.py +137 -0
  379. django_cfg/modules/django_unfold/callbacks/base.py +198 -7
  380. django_cfg/modules/django_unfold/callbacks/main.py +102 -10
  381. django_cfg/modules/django_unfold/dashboard.py +65 -43
  382. django_cfg/modules/django_unfold/models/config.py +13 -12
  383. django_cfg/modules/django_unfold/models/navigation.py +8 -3
  384. django_cfg/modules/django_unfold/models/tabs.py +2 -2
  385. django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
  386. django_cfg/registry/core.py +24 -26
  387. django_cfg/registry/modules.py +5 -2
  388. django_cfg/registry/services.py +20 -3
  389. django_cfg/registry/third_party.py +8 -8
  390. django_cfg/static/admin/css/dashboard.css +260 -0
  391. django_cfg/static/admin/js/commands.js +171 -0
  392. django_cfg/static/admin/js/dashboard.js +126 -0
  393. django_cfg/templates/admin/components/management_commands.js +375 -0
  394. django_cfg/templates/admin/components/progress_bar.html +18 -23
  395. django_cfg/templates/admin/index.html +48 -20
  396. django_cfg/templates/admin/index_new.html +106 -0
  397. django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
  398. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
  399. django_cfg/templates/admin/sections/commands_section.html +626 -0
  400. django_cfg/templates/admin/sections/overview_section.html +112 -0
  401. django_cfg/templates/admin/sections/stats_section.html +35 -0
  402. django_cfg/templates/admin/sections/system_section.html +99 -0
  403. django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
  404. django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
  405. django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
  406. django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
  407. django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
  408. django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
  409. django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
  410. django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
  411. django_cfg/templatetags/django_cfg.py +7 -1
  412. django_cfg/utils/smart_defaults.py +4 -4
  413. django_cfg-1.4.0.dist-info/METADATA +920 -0
  414. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/RECORD +425 -196
  415. django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
  416. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
  417. django_cfg/core/generation.py +0 -621
  418. django_cfg/management/commands/validate_config.py +0 -189
  419. django_cfg/models/database.py +0 -480
  420. django_cfg/models/drf.py +0 -272
  421. django_cfg/models/ngrok.py +0 -122
  422. django_cfg/models/services.py +0 -440
  423. django_cfg/models/tasks.py +0 -550
  424. django_cfg/modules/django_twilio/service.py +0 -942
  425. django_cfg/template_archive/django_sample.zip +0 -0
  426. django_cfg/templates/rest_framework/api.html +0 -12
  427. django_cfg/utils/toolkit.py +0 -703
  428. django_cfg-1.3.11.dist-info/METADATA +0 -1029
  429. /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
  430. /django_cfg/core/{environment.py → environment/detector.py} +0 -0
  431. /django_cfg/models/{cors.py → api/cors.py} +0 -0
  432. /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
  433. /django_cfg/models/{base.py → base/config.py} +0 -0
  434. /django_cfg/models/{cfg.py → base/module.py} +0 -0
  435. /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
  436. /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
  437. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/WHEEL +0 -0
  438. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/entry_points.txt +0 -0
  439. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,395 +1,116 @@
1
1
  """
2
2
  Django CFG Create Project Command
3
3
 
4
- Creates a new Django project using django-cfg sample template.
4
+ Creates a new Django project by downloading from GitHub.
5
5
  """
6
6
 
7
7
  import click
8
8
  import shutil
9
- import os
9
+ import urllib.request
10
10
  from pathlib import Path
11
- from typing import Optional
12
11
  import tempfile
13
- import subprocess
14
- import sys
15
- from rich.console import Console
16
- from rich.panel import Panel
17
- from rich.text import Text
18
-
19
- from ..utils import find_template_archive, validate_project_name
20
-
21
- console = Console()
22
-
23
-
24
- def show_thank_you_message():
25
- """Display a beautiful thank you message with company info."""
26
- # Create styled text
27
- title = Text("Thank you for using django-cfg!", style="bold cyan")
28
-
29
- # Company info with clickable link
30
- company_text = Text()
31
- company_text.append("Developed by ", style="white")
32
- company_text.append("Unrealon.com", style="bold blue underline")
33
- company_text.append(" — Complex parsers on demand", style="white")
34
-
35
- link_text = Text()
36
- link_text.append("🌐 ", style="green")
37
- link_text.append("https://unrealon.com", style="blue underline")
38
-
39
- # Create panel content
40
- panel_content = Text()
41
- panel_content.append(title)
42
- panel_content.append("\n\n")
43
- panel_content.append(company_text)
44
- panel_text = Text()
45
- panel_text.append("\n")
46
- panel_text.append(link_text)
47
- panel_content.append(panel_text)
48
-
49
- # Display beautiful panel
50
- console.print()
51
- console.print(Panel(
52
- panel_content,
53
- title="🚀 Django CFG",
54
- title_align="center",
55
- border_style="bright_blue",
56
- padding=(1, 2)
57
- ))
58
-
59
-
60
- def extract_template(archive_path: Path, target_path: Path, project_name: str) -> None:
61
- """Extract template archive to target directory with project name replacements."""
62
- import zipfile
63
-
64
- click.echo(f"📂 Extracting template from archive...")
65
-
66
- target_path = Path(target_path)
67
- target_path.mkdir(parents=True, exist_ok=True)
68
-
69
- files_extracted = 0
70
- try:
71
- with zipfile.ZipFile(archive_path, 'r') as archive:
72
- for member in archive.namelist():
73
- # Extract file
74
- archive.extract(member, target_path)
75
- files_extracted += 1
76
-
77
- # Apply project name replacements to text files
78
- extracted_file = target_path / member
79
- if extracted_file.is_file() and should_process_file_for_replacements(extracted_file):
80
- replace_project_name(extracted_file, project_name)
81
-
82
- click.echo(f"✅ Extracted {files_extracted} files from template")
83
-
84
- except zipfile.BadZipFile:
85
- raise ValueError(f"Invalid template archive: {archive_path}")
86
- except Exception as e:
87
- raise RuntimeError(f"Failed to extract template: {e}")
12
+ import zipfile
88
13
 
14
+ # GitHub template URL
15
+ TEMPLATE_URL = "https://github.com/markolofsen/django-cfg/archive/refs/heads/main.zip"
89
16
 
90
- def should_process_file_for_replacements(file_path: Path) -> bool:
91
- """Check if file should be processed for project name replacements."""
92
- text_extensions = {'.py', '.yaml', '.yml', '.json', '.toml', '.txt', '.md', '.html', '.css', '.js', '.conf', '.sh'}
93
- return file_path.suffix.lower() in text_extensions
94
17
 
18
+ def download_template(url: str) -> Path:
19
+ """Download template archive from GitHub."""
20
+ click.echo("📥 Downloading template from GitHub...")
95
21
 
96
- def replace_project_name(file_path: Path, project_name: str) -> None:
97
- """Replace template project name with actual project name."""
98
22
  try:
99
- with open(file_path, 'r', encoding='utf-8') as f:
100
- content = f.read()
101
-
102
- # Replace common template placeholders
103
- replacements = {
104
- "Django CFG Sample": project_name,
105
- "django-cfg-sample": project_name.lower().replace(" ", "-"),
106
- "django_cfg_sample": project_name.lower().replace(" ", "_").replace("-", "_"),
107
- "DjangoCfgSample": "".join(word.capitalize() for word in project_name.replace("-", " ").replace("_", " ").split()),
108
- }
109
-
110
- for old, new in replacements.items():
111
- content = content.replace(old, new)
112
-
113
- with open(file_path, 'w', encoding='utf-8') as f:
114
- f.write(content)
115
-
116
- except (UnicodeDecodeError, PermissionError, OSError):
117
- # Skip binary files or files we can't process
118
- pass
119
-
120
-
121
-
122
-
123
- def create_readme(target_path: Path, project_name: str) -> None:
124
- """Create a README.md file for the new project."""
125
- readme_content = f"""# {project_name}
126
-
127
- A Django project powered by **django-cfg** - the production-ready Django configuration framework.
128
-
129
- ## 🚀 Features
130
-
131
- This project includes:
132
-
133
- - **🔧 Type-safe Configuration** - Pydantic v2 models with validation
134
- - **📱 Twilio Integration** - OTP services (WhatsApp, SMS, Email)
135
- - **📧 Email Services** - SendGrid integration
136
- - **💬 Telegram Bot** - Notifications and alerts
137
- - **🎨 Modern Admin** - Unfold admin interface
138
- - **📊 API Documentation** - Auto-generated OpenAPI/Swagger
139
- - **🔐 JWT Authentication** - Ready-to-use auth system
140
- - **🗃️ Multi-database Support** - With automatic routing
141
- - **⚡ Background Tasks** - Dramatiq task processing
142
- - **🌐 Ngrok Integration** - Easy webhook testing
143
- - **🐳 Docker Ready** - Complete containerization
144
-
145
- ## 📦 Quick Start
146
-
147
- 1. **Install Dependencies**
148
- ```bash
149
- # Using Poetry (recommended)
150
- poetry install
151
-
152
- # Or using pip
153
- pip install -r requirements.txt
154
- ```
155
-
156
- 2. **Configure Environment**
157
- ```bash
158
- # Copy and edit configuration
159
- cp api/environment/config.dev.yaml api/environment/config.local.yaml
160
- # Edit config.local.yaml with your settings
161
- ```
162
-
163
- 3. **Setup Database**
164
- ```bash
165
- python manage.py migrate
166
- python manage.py createsuperuser
167
- ```
168
-
169
- 4. **Populate Sample Data** (Optional)
170
- ```bash
171
- python manage.py populate_sample_data
172
- ```
173
-
174
- 5. **Run Development Server**
175
- ```bash
176
- python manage.py runserver
177
- ```
178
-
179
- ## 🔧 Configuration
180
-
181
- Edit `api/environment/config.dev.yaml` (or create `config.local.yaml`) to configure:
182
-
183
- - **Database connections** (PostgreSQL, MySQL, SQLite)
184
- - **Email settings** (SMTP, SendGrid)
185
- - **Twilio credentials** (Account SID, Auth Token, Verify Service SID)
186
- - **Telegram bot** (Bot Token, Chat ID)
187
- - **API keys** (OpenAI, OpenRouter, etc.)
188
- - **Cache settings** (Redis)
189
-
190
- ## 📱 Twilio OTP Usage
191
-
192
- ```python
193
- from django_cfg import send_sms_otp, send_whatsapp_otp, send_email_otp, verify_otp
194
-
195
- # Send SMS OTP
196
- success, message = send_sms_otp("+1234567890")
197
-
198
- # Send WhatsApp OTP with SMS fallback
199
- success, message = send_whatsapp_otp("+1234567890", fallback_to_sms=True)
200
-
201
- # Send Email OTP
202
- success, message, code = send_email_otp("user@example.com")
203
-
204
- # Verify OTP
205
- is_valid, result = verify_otp("+1234567890", "123456")
206
- ```
23
+ # Create temp file
24
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.zip')
25
+ temp_path = Path(temp_file.name)
26
+
27
+ # Download with progress
28
+ with urllib.request.urlopen(url) as response:
29
+ total_size = int(response.headers.get('content-length', 0))
30
+ downloaded = 0
31
+ chunk_size = 8192
32
+
33
+ with open(temp_path, 'wb') as f:
34
+ while True:
35
+ chunk = response.read(chunk_size)
36
+ if not chunk:
37
+ break
38
+ f.write(chunk)
39
+ downloaded += len(chunk)
40
+
41
+ if total_size > 0:
42
+ progress = (downloaded / total_size) * 100
43
+ click.echo(f"\r Progress: {progress:.1f}%", nl=False)
44
+
45
+ click.echo("\n✅ Template downloaded successfully")
46
+ return temp_path
207
47
 
208
- ## 🐳 Docker Deployment
48
+ except Exception as e:
49
+ raise RuntimeError(f"Failed to download template: {e}")
209
50
 
210
- ```bash
211
- # Build and run with Docker Compose
212
- docker-compose up -d
213
51
 
214
- # Or use the production setup
215
- docker-compose -f docker-compose.yml -f docker-compose.nginx.yml up -d
216
- ```
52
+ def extract_template(archive_path: Path, target_path: Path) -> None:
53
+ """Extract template archive to target directory."""
54
+ click.echo("📂 Extracting template...")
217
55
 
218
- ## 📚 Documentation
56
+ try:
57
+ with zipfile.ZipFile(archive_path, 'r') as archive:
58
+ members = archive.namelist()
219
59
 
220
- - **Admin Interface**: `http://localhost:8000/admin/`
221
- - **API Documentation**: `http://localhost:8000/api/schema/swagger-ui/`
222
- - **Django CFG Docs**: [djangocfg.com](https://djangocfg.com)
60
+ # Find the root folder name (django-cfg-main)
61
+ root_folder = members[0].split('/')[0] if members else None
223
62
 
224
- ## 🛠️ Development
63
+ if not root_folder:
64
+ raise ValueError("Archive structure is invalid")
225
65
 
226
- ```bash
227
- # Run with Ngrok for webhook testing
228
- python manage.py runserver_ngrok
229
-
230
- # Generate OpenAPI clients
231
- python manage.py generate_openapi_clients
232
-
233
- # Translate content (if using i18n)
234
- python manage.py translate_content
235
- ```
236
-
237
- ## 📁 Project Structure
66
+ # Path to django project in archive: django-cfg-main/libs/django_cfg_example/django/
67
+ template_prefix = f"{root_folder}/libs/django_cfg_example/django/"
238
68
 
239
- ```
240
- {project_name.lower().replace(" ", "_")}/
241
- ├── api/ # Configuration and settings
242
- │ ├── config.py # Main django-cfg configuration
243
- │ ├── environment/ # Environment-specific configs
244
- │ ├── settings.py # Generated Django settings
245
- │ └── urls.py # Root URL configuration
246
- ├── apps/ # Django applications
247
- │ ├── blog/ # Blog app example
248
- │ ├── profiles/ # User profiles
249
- │ └── shop/ # E-commerce example
250
- ├── core/ # Core utilities and management commands
251
- ├── docker/ # Docker configuration
252
- ├── static/ # Static files
253
- ├── templates/ # Django templates
254
- └── manage.py # Django management script
255
- ```
69
+ # Extract only files from the django/ folder
70
+ extracted_files = 0
71
+ for member in members:
72
+ # Skip if not in template path
73
+ if not member.startswith(template_prefix):
74
+ continue
256
75
 
257
- ## 🤝 Contributing
76
+ # Skip the django_cfg folder (local package)
77
+ if f"{root_folder}/libs/django_cfg_example/django_cfg/" in member:
78
+ continue
258
79
 
259
- This project uses **django-cfg** for configuration management.
260
- For more information, visit: [https://github.com/markolofsen/django-cfg](https://github.com/markolofsen/django-cfg)
80
+ # Calculate relative path (remove template_prefix)
81
+ relative_path = member[len(template_prefix):]
261
82
 
262
- ## 📄 License
83
+ # Skip empty paths (directory markers)
84
+ if not relative_path:
85
+ continue
263
86
 
264
- MIT License - see LICENSE file for details.
87
+ # Target file path
88
+ target_file = target_path / relative_path
265
89
 
266
- ---
90
+ # Extract file
91
+ if member.endswith('/'):
92
+ # Create directory
93
+ target_file.mkdir(parents=True, exist_ok=True)
94
+ else:
95
+ # Create parent directories
96
+ target_file.parent.mkdir(parents=True, exist_ok=True)
267
97
 
268
- **Powered by django-cfg** 🚀
269
- """
270
-
271
- readme_path = target_path / "README.md"
272
- with open(readme_path, 'w', encoding='utf-8') as f:
273
- f.write(readme_content)
98
+ # Extract file content
99
+ with archive.open(member) as source:
100
+ with open(target_file, 'wb') as target:
101
+ target.write(source.read())
274
102
 
103
+ extracted_files += 1
275
104
 
276
- def run_command(target_path: Path, command: list, description: str, use_poetry: bool = True, check: bool = True) -> tuple[bool, str]:
277
- """
278
- Universal function to run commands with Poetry or pip.
279
-
280
- Args:
281
- target_path: Project directory
282
- command: Command to run (without poetry/python prefix)
283
- description: Description for user feedback
284
- use_poetry: Use Poetry if True, pip/python if False
285
- check: Raise exception on error if True
286
-
287
- Returns:
288
- (success: bool, output: str)
289
- """
290
- try:
291
- if use_poetry:
292
- cmd = ["poetry", "run"] + command
293
- else:
294
- # For pip/python commands, use system python
295
- if command[0] == "python":
296
- cmd = [sys.executable] + command[1:]
297
- else:
298
- cmd = command
299
-
300
- result = subprocess.run(
301
- cmd,
302
- cwd=target_path,
303
- check=check,
304
- capture_output=True,
305
- text=True
306
- )
307
-
308
- return True, result.stdout
309
-
310
- except subprocess.CalledProcessError as e:
311
- return False, f"Error: {e}\nstdout: {e.stdout}\nstderr: {e.stderr}"
312
- except FileNotFoundError as e:
313
- return False, f"Command not found: {e}"
314
-
315
-
316
- def install_dependencies(target_path: Path, use_poetry: bool = True) -> bool:
317
- """Install project dependencies using Poetry or pip."""
318
- click.echo("📦 Installing dependencies...")
319
-
320
- if use_poetry:
321
- success, output = run_command(target_path, ["poetry", "install"], "Installing with Poetry", use_poetry=False)
322
- else:
323
- success, output = run_command(target_path, ["python", "-m", "pip", "install", "-r", "requirements.txt"], "Installing with pip", use_poetry=False)
324
-
325
- if success:
326
- click.echo("✅ Dependencies installed successfully")
327
- return True
328
- else:
329
- click.echo(f"⚠️ Warning: Failed to install dependencies: {output}", err=True)
330
- return False
331
-
332
-
333
- def setup_project_structure(target_path: Path) -> bool:
334
- """Create necessary directories for the project."""
335
- try:
336
- # Create db directory for SQLite database
337
- db_dir = target_path / "db"
338
- db_dir.mkdir(exist_ok=True)
339
- click.echo(f"📁 Created database directory: {db_dir}")
340
-
341
- # Create cache directory
342
- cache_dir = target_path / "cache"
343
- cache_dir.mkdir(exist_ok=True)
344
- click.echo(f"📁 Created cache directory: {cache_dir}")
345
-
346
- return True
105
+ click.echo(f"✅ Template extracted successfully ({extracted_files} files)")
106
+
107
+ except zipfile.BadZipFile:
108
+ raise ValueError(f"Invalid template archive")
347
109
  except Exception as e:
348
- click.echo(f"⚠️ Warning: Failed to create project directories: {e}", err=True)
349
- return False
350
-
351
-
352
- def run_initial_migrations(target_path: Path, use_poetry: bool = True) -> bool:
353
- """Run initial Django migrations."""
354
- click.echo("🔄 Running initial migrations...")
355
-
356
- # Try cli migrator first, fallback to manage.py migrate
357
- success, output = run_command(target_path, ["cli", "migrator"], "Running migrations", use_poetry, check=False)
358
-
359
- if not success:
360
- click.echo(" Falling back to manage.py migrate...")
361
- success, output = run_command(target_path, ["python", "manage.py", "migrate"], "Running migrations", use_poetry)
362
-
363
- if success:
364
- click.echo("✅ Initial migrations completed successfully")
365
- return True
366
- else:
367
- click.echo(f"⚠️ Warning: Failed to run migrations: {output}", err=True)
368
- return False
369
-
370
-
371
- def populate_sample_data(target_path: Path, use_poetry: bool = True) -> bool:
372
- """Populate database with sample data."""
373
- click.echo("👥 Populating sample data (users, blog posts, products)...")
374
-
375
- success, output = run_command(
376
- target_path,
377
- ["python", "manage.py", "populate_sample_data", "--users", "10", "--posts", "20", "--products", "30"],
378
- "Populating sample data",
379
- use_poetry
380
- )
381
-
382
- if success:
383
- click.echo("✅ Sample data populated successfully")
384
- click.echo(" 📝 Created 10 test users, 20 blog posts, 30 products")
385
- return True
386
- else:
387
- click.echo(f"⚠️ Warning: Failed to populate sample data: {output}", err=True)
388
- return False
110
+ raise RuntimeError(f"Failed to extract template: {e}")
389
111
 
390
112
 
391
113
  @click.command()
392
- @click.argument("project_name")
393
114
  @click.option(
394
115
  "--path",
395
116
  "-p",
@@ -397,177 +118,73 @@ def populate_sample_data(target_path: Path, use_poetry: bool = True) -> bool:
397
118
  default=".",
398
119
  help="Directory where to create the project (default: current directory)"
399
120
  )
400
- @click.option(
401
- "--no-deps",
402
- is_flag=True,
403
- help="Skip automatic dependency installation"
404
- )
405
- @click.option(
406
- "--use-pip",
407
- is_flag=True,
408
- help="Use pip instead of Poetry for dependency installation"
409
- )
410
121
  @click.option(
411
122
  "--force",
123
+ "-f",
412
124
  is_flag=True,
413
- help="Overwrite existing directory if it exists"
414
- )
415
- @click.option(
416
- "--no-setup",
417
- is_flag=True,
418
- help="Skip automatic project setup (directories, migrations)"
125
+ help="Overwrite existing files if they exist"
419
126
  )
420
- @click.option(
421
- "--no-sample-data",
422
- is_flag=True,
423
- help="Skip sample data population (users, posts, products)"
424
- )
425
- def create_project(project_name: str, path: str, no_deps: bool, use_pip: bool, force: bool, no_setup: bool, no_sample_data: bool):
127
+ def create_project(path: str, force: bool):
426
128
  """
427
129
  🚀 Create a new Django project with django-cfg
428
-
429
- Creates a complete Django project with type-safe configuration,
430
- modern admin interface, API documentation, and production-ready setup.
431
-
432
- PROJECT_NAME: Name of the new Django project
433
-
130
+
131
+ Downloads the latest django-cfg template from GitHub and extracts it.
132
+
434
133
  Examples:
435
-
436
- # Create project in current directory
437
- django-cfg create-project "My Awesome Project"
438
-
439
- # Create project in specific directory
440
- django-cfg create-project "My Project" --path ./projects/
441
-
442
- # Skip dependency installation
443
- django-cfg create-project "My Project" --no-deps
444
-
445
- # Use pip instead of Poetry
446
- django-cfg create-project "My Project" --use-pip
447
-
448
- # Skip automatic setup (directories, migrations)
449
- django-cfg create-project "My Project" --no-setup
450
-
451
- # Skip sample data creation (users, posts, products)
452
- django-cfg create-project "My Project" --no-sample-data
134
+
135
+ # Extract to current directory
136
+ django-cfg create-project
137
+
138
+ # Extract to specific directory
139
+ django-cfg create-project --path ./my-project/
140
+
141
+ # Overwrite existing files
142
+ django-cfg create-project --force
453
143
  """
454
-
455
- # Validate project name
456
- if not validate_project_name(project_name):
457
- click.echo("❌ Invalid project name", err=True)
458
- return
459
-
144
+
460
145
  # Determine target path
461
- base_path = Path(path).resolve()
462
- project_dir_name = project_name.lower().replace(" ", "_").replace("-", "_")
463
- target_path = base_path / project_dir_name
464
-
465
- # Check if target directory exists
466
- if target_path.exists():
146
+ target_path = Path(path).resolve()
147
+
148
+ # Check if target directory exists and has files
149
+ if target_path.exists() and any(target_path.iterdir()):
467
150
  if not force:
468
- click.echo(f"❌ Directory '{target_path}' already exists. Use --force to overwrite.", err=True)
151
+ click.echo(f"❌ Directory '{target_path}' is not empty. Use --force to overwrite.", err=True)
469
152
  return
470
153
  else:
471
- click.echo(f"⚠️ Removing existing directory '{target_path}'...")
472
- shutil.rmtree(target_path)
473
-
154
+ click.echo(f"⚠️ Directory is not empty, files will be overwritten...")
155
+
156
+ temp_archive = None
157
+
474
158
  try:
475
- # Get template archive path
476
- archive_path = find_template_archive()
477
- if not archive_path:
478
- raise FileNotFoundError(
479
- "Could not find django_sample.zip template archive. "
480
- "Please ensure django-cfg is properly installed or run 'python scripts/template_manager.py create' in development."
481
- )
482
- click.echo(f"📋 Using template archive: {archive_path.name}")
483
-
159
+ click.echo(f"🚀 Creating Django project from GitHub")
160
+ click.echo(f"📁 Target location: {target_path}")
161
+ click.echo()
162
+
163
+ # Download template from GitHub
164
+ temp_archive = download_template(TEMPLATE_URL)
165
+
484
166
  # Create target directory
485
167
  target_path.mkdir(parents=True, exist_ok=True)
486
-
487
- # Extract template files
488
- extract_template(archive_path, target_path, project_name)
489
-
490
- # Create additional files
491
- create_readme(target_path, project_name)
492
-
493
- click.echo(f"✅ Project '{project_name}' created successfully!")
168
+
169
+ # Extract template
170
+ extract_template(temp_archive, target_path)
171
+
172
+ click.echo()
173
+ click.echo(f"✅ Project created successfully!")
494
174
  click.echo(f"📁 Location: {target_path}")
495
-
496
- # Setup project structure
497
- if not no_setup:
498
- click.echo("\n🔧 Setting up project structure...")
499
- setup_project_structure(target_path)
500
-
501
- # Install dependencies if requested
502
- deps_installed = False
503
- if not no_deps:
504
- install_success = install_dependencies(target_path, not use_pip)
505
- if install_success:
506
- deps_installed = True
507
- else:
508
- click.echo("💡 You can install dependencies manually later:")
509
- if not use_pip:
510
- click.echo(" poetry install")
511
- else:
512
- click.echo(" pip install -r requirements.txt")
513
-
514
- # Run initial setup if dependencies were installed
515
- if deps_installed and not no_setup:
516
- click.echo("\n🔄 Running initial project setup...")
517
- migration_success = run_initial_migrations(target_path, not use_pip)
518
-
519
- if migration_success:
520
- # Populate sample data if requested
521
- if not no_sample_data:
522
- sample_data_success = populate_sample_data(target_path, not use_pip)
523
- if sample_data_success:
524
- click.echo("✅ Project is ready to use with sample data!")
525
- click.echo("💡 Login credentials: username/password for any test user")
526
- else:
527
- click.echo("✅ Project is ready to use!")
528
- click.echo("💡 You can populate sample data later:")
529
- if not use_pip:
530
- click.echo(" poetry run python manage.py populate_sample_data")
531
- else:
532
- click.echo(" python manage.py populate_sample_data")
533
- else:
534
- click.echo("✅ Project is ready to use!")
535
- else:
536
- click.echo("💡 You can run migrations manually later:")
537
- if not use_pip:
538
- click.echo(" poetry run cli migrator")
539
- else:
540
- click.echo(" python manage.py migrate")
541
-
175
+
542
176
  # Show next steps
543
- click.echo("\n🎉 Your Django CFG project is ready!")
544
- click.echo("\n📋 Next steps:")
545
- click.echo(f" cd {project_dir_name}")
546
-
547
- if no_deps:
548
- if not use_pip:
549
- click.echo(" poetry install")
550
- else:
551
- click.echo(" pip install -r requirements.txt")
552
-
553
- if no_setup or not deps_installed:
554
- click.echo(" # Edit api/environment/config.dev.yaml with your settings")
555
- if not deps_installed:
556
- if not use_pip:
557
- click.echo(" poetry run cli migrator")
558
- else:
559
- click.echo(" python manage.py migrate")
560
- click.echo(" python manage.py createsuperuser")
561
- else:
562
- click.echo(" # Edit api/environment/config.dev.yaml with your settings")
563
- click.echo(" python manage.py createsuperuser")
564
-
565
- if not use_pip:
566
- click.echo(" poetry run cli runserver")
567
- else:
568
- click.echo(" python manage.py runserver")
569
-
570
- click.echo("\n💡 Features included:")
177
+ click.echo()
178
+ click.echo("📋 Next steps:")
179
+ if target_path != Path.cwd():
180
+ click.echo(f" cd {target_path}")
181
+ click.echo(" poetry install # or: pip install -r requirements.txt")
182
+ click.echo(" python manage.py migrate")
183
+ click.echo(" python manage.py createsuperuser")
184
+ click.echo(" python manage.py runserver")
185
+
186
+ click.echo()
187
+ click.echo("💡 Features included:")
571
188
  click.echo(" 🔧 Type-safe configuration with Pydantic v2")
572
189
  click.echo(" 📱 Twilio integration (WhatsApp, SMS, Email OTP)")
573
190
  click.echo(" 📧 Email services with SendGrid")
@@ -578,25 +195,19 @@ def create_project(project_name: str, path: str, no_deps: bool, use_pip: bool, f
578
195
  click.echo(" 🗃️ Multi-database support with routing")
579
196
  click.echo(" ⚡ Background task processing")
580
197
  click.echo(" 🐳 Docker deployment ready")
581
-
582
- # click.echo(f"\n📚 Documentation: https://djangocfg.com")
583
-
584
- # Beautiful thank you message
585
- show_thank_you_message()
586
-
587
- except FileNotFoundError as e:
588
- click.echo(f"❌ Template archive not found: {e}", err=True)
589
- click.echo("💡 Make sure django-cfg is properly installed")
590
- click.echo("💡 In development, run: python scripts/template_manager.py create")
591
-
592
- except (ValueError, RuntimeError) as e:
593
- click.echo(f"❌ Template error: {e}", err=True)
594
- # Clean up on error
595
- if target_path.exists():
596
- shutil.rmtree(target_path, ignore_errors=True)
597
-
198
+
199
+ click.echo()
200
+ click.echo("📚 Documentation: https://github.com/markolofsen/django-cfg")
201
+ click.echo("🌐 Developed by Unrealon.com — Complex parsers on demand")
202
+
598
203
  except Exception as e:
599
204
  click.echo(f"❌ Error creating project: {e}", err=True)
600
205
  # Clean up on error
601
206
  if target_path.exists():
602
207
  shutil.rmtree(target_path, ignore_errors=True)
208
+ raise
209
+
210
+ finally:
211
+ # Clean up temp file
212
+ if temp_archive and temp_archive.exists():
213
+ temp_archive.unlink()