django-cfg 1.3.13__py3-none-any.whl → 1.4.3__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 (446) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/user_admin.py +39 -16
  3. django_cfg/apps/accounts/serializers/profile.py +1 -1
  4. django_cfg/apps/accounts/services/otp_service.py +18 -11
  5. django_cfg/apps/accounts/signals.py +15 -24
  6. django_cfg/apps/accounts/utils/notifications.py +217 -358
  7. django_cfg/apps/accounts/views/otp.py +2 -2
  8. django_cfg/apps/accounts/views/webhook.py +1 -1
  9. django_cfg/apps/agents/core/django_agent.py +1 -1
  10. django_cfg/apps/agents/examples/__init__.py +3 -0
  11. django_cfg/apps/agents/examples/simple_example.py +161 -0
  12. django_cfg/apps/api/commands/views.py +66 -83
  13. django_cfg/apps/api/health/drf_views.py +269 -0
  14. django_cfg/apps/api/health/serializers.py +45 -0
  15. django_cfg/apps/api/health/urls.py +6 -1
  16. django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
  17. django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
  18. django_cfg/apps/knowbase/admin/document_admin.py +136 -270
  19. django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
  20. django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
  21. django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
  22. django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
  23. django_cfg/apps/knowbase/config/constance_fields.py +1 -1
  24. django_cfg/apps/knowbase/config/settings.py +2 -2
  25. django_cfg/apps/knowbase/examples/__init__.py +3 -0
  26. django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
  27. django_cfg/apps/knowbase/mixins/__init__.py +19 -2
  28. django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
  29. django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
  30. django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
  31. django_cfg/apps/knowbase/mixins/creator.py +10 -10
  32. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
  33. django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
  34. django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
  35. django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
  36. django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
  37. django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
  38. django_cfg/apps/knowbase/mixins/service.py +2 -2
  39. django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
  40. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
  41. django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
  42. django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
  43. django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
  44. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
  45. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
  46. django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
  47. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
  48. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
  49. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
  50. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
  51. django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
  52. django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
  53. django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
  54. django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
  55. django_cfg/apps/knowbase/services/embedding/models.py +18 -14
  56. django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
  57. django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
  58. django_cfg/apps/leads/tests.py +1 -1
  59. django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
  60. django_cfg/apps/payments/admin/balance_admin.py +1 -1
  61. django_cfg/apps/payments/admin/currencies_admin.py +1 -1
  62. django_cfg/apps/payments/admin/payments_admin.py +1 -1
  63. django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
  64. django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
  65. django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
  66. django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
  67. django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
  68. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
  69. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
  70. django_cfg/apps/payments/admin_interface/views/base.py +29 -2
  71. django_cfg/apps/payments/apps.py +1 -1
  72. django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
  73. django_cfg/apps/payments/config/helpers.py +3 -2
  74. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
  75. django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
  76. django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
  77. django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
  78. django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
  79. django_cfg/apps/payments/management/commands/test_providers.py +1 -1
  80. django_cfg/apps/payments/middleware/api_access.py +1 -1
  81. django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
  82. django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
  83. django_cfg/apps/payments/models/balance.py +2 -2
  84. django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
  85. django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
  86. django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
  87. django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
  88. django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
  89. django_cfg/apps/payments/models/payments.py +2 -2
  90. django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
  91. django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
  92. django_cfg/apps/payments/services/core/base.py +1 -1
  93. django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
  94. django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
  95. django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
  96. django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
  97. django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
  98. django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
  99. django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
  100. django_cfg/apps/payments/services/core/payment_service.py +124 -612
  101. django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
  102. django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
  103. django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
  104. django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
  105. django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
  106. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
  107. django_cfg/apps/payments/services/providers/base.py +1 -1
  108. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
  109. django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
  110. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
  111. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
  112. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
  113. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
  114. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
  115. django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
  116. django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
  117. django_cfg/apps/payments/services/providers/registry.py +1 -1
  118. django_cfg/apps/payments/services/providers/sync_service.py +1 -1
  119. django_cfg/apps/payments/signals/__init__.py +1 -1
  120. django_cfg/apps/payments/signals/api_key_signals.py +1 -1
  121. django_cfg/apps/payments/signals/balance_signals.py +1 -1
  122. django_cfg/apps/payments/signals/payment_signals.py +1 -1
  123. django_cfg/apps/payments/signals/subscription_signals.py +1 -1
  124. django_cfg/apps/payments/views/api/api_keys.py +1 -1
  125. django_cfg/apps/payments/views/api/balances.py +1 -1
  126. django_cfg/apps/payments/views/api/base.py +1 -1
  127. django_cfg/apps/payments/views/api/currencies.py +1 -1
  128. django_cfg/apps/payments/views/api/payments.py +1 -1
  129. django_cfg/apps/payments/views/api/subscriptions.py +1 -1
  130. django_cfg/apps/payments/views/api/webhooks.py +1 -1
  131. django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
  132. django_cfg/apps/payments/views/serializers/balances.py +1 -1
  133. django_cfg/apps/payments/views/serializers/currencies.py +1 -1
  134. django_cfg/apps/payments/views/serializers/payments.py +1 -1
  135. django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
  136. django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
  137. django_cfg/apps/support/admin/support_admin.py +21 -13
  138. django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
  139. django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
  140. django_cfg/apps/support/utils/support_email_service.py +1 -1
  141. django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
  142. django_cfg/apps/tasks/utils/simulator.py +1 -1
  143. django_cfg/apps/tasks/views/dashboard.py +33 -3
  144. django_cfg/apps/urls.py +5 -1
  145. django_cfg/cli/README.md +57 -471
  146. django_cfg/cli/commands/create_project.py +140 -529
  147. django_cfg/cli/main.py +13 -10
  148. django_cfg/core/__init__.py +63 -6
  149. django_cfg/core/base/__init__.py +5 -0
  150. django_cfg/core/base/config_model.py +652 -0
  151. django_cfg/core/builders/__init__.py +11 -0
  152. django_cfg/core/builders/apps_builder.py +258 -0
  153. django_cfg/core/builders/middleware_builder.py +115 -0
  154. django_cfg/core/builders/security_builder.py +96 -0
  155. django_cfg/core/config.py +20 -892
  156. django_cfg/core/constants.py +69 -0
  157. django_cfg/core/environment/__init__.py +9 -0
  158. django_cfg/core/exceptions.py +45 -298
  159. django_cfg/core/generation/__init__.py +51 -0
  160. django_cfg/core/generation/core_generators/__init__.py +0 -0
  161. django_cfg/core/generation/core_generators/settings.py +90 -0
  162. django_cfg/core/generation/core_generators/static.py +82 -0
  163. django_cfg/core/generation/core_generators/templates.py +141 -0
  164. django_cfg/core/generation/data_generators/__init__.py +15 -0
  165. django_cfg/core/generation/data_generators/cache.py +132 -0
  166. django_cfg/core/generation/data_generators/database.py +117 -0
  167. django_cfg/core/generation/generation.py +92 -0
  168. django_cfg/core/generation/integration_generators/__init__.py +21 -0
  169. django_cfg/core/generation/integration_generators/api.py +237 -0
  170. django_cfg/core/generation/integration_generators/sessions.py +65 -0
  171. django_cfg/core/generation/integration_generators/tailwind.py +54 -0
  172. django_cfg/core/generation/integration_generators/tasks.py +92 -0
  173. django_cfg/core/generation/integration_generators/third_party.py +144 -0
  174. django_cfg/core/generation/orchestrator.py +285 -0
  175. django_cfg/core/generation/protocols.py +30 -0
  176. django_cfg/core/generation/security_generators/__init__.py +0 -0
  177. django_cfg/core/generation/utility_generators/__init__.py +24 -0
  178. django_cfg/core/generation/utility_generators/email.py +58 -0
  179. django_cfg/core/generation/utility_generators/i18n.py +66 -0
  180. django_cfg/core/generation/utility_generators/limits.py +58 -0
  181. django_cfg/core/generation/utility_generators/logging.py +66 -0
  182. django_cfg/core/generation/utility_generators/security.py +101 -0
  183. django_cfg/core/generation/utils/__init__.py +0 -0
  184. django_cfg/core/generation/utils/helpers.py +32 -0
  185. django_cfg/core/integration/__init__.py +18 -25
  186. django_cfg/core/integration/display/startup.py +146 -133
  187. django_cfg/core/integration/url_integration.py +13 -2
  188. django_cfg/core/services/__init__.py +5 -0
  189. django_cfg/core/services/config_service.py +121 -0
  190. django_cfg/core/state/__init__.py +9 -0
  191. django_cfg/core/state/registry.py +84 -0
  192. django_cfg/core/types/__init__.py +15 -0
  193. django_cfg/core/types/aliases.py +15 -0
  194. django_cfg/core/types/enums.py +49 -0
  195. django_cfg/dashboard/DEBUG_README.md +105 -0
  196. django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
  197. django_cfg/dashboard/__init__.py +24 -0
  198. django_cfg/dashboard/components.py +308 -0
  199. django_cfg/dashboard/debug.py +176 -0
  200. django_cfg/dashboard/management/__init__.py +0 -0
  201. django_cfg/dashboard/management/commands/__init__.py +0 -0
  202. django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
  203. django_cfg/dashboard/sections/__init__.py +1 -0
  204. django_cfg/dashboard/sections/base.py +128 -0
  205. django_cfg/dashboard/sections/commands.py +32 -0
  206. django_cfg/dashboard/sections/overview.py +394 -0
  207. django_cfg/dashboard/sections/stats.py +48 -0
  208. django_cfg/dashboard/sections/system.py +73 -0
  209. django_cfg/management/commands/check_settings.py +6 -2
  210. django_cfg/management/commands/clear_constance.py +6 -1
  211. django_cfg/management/commands/create_token.py +5 -4
  212. django_cfg/management/commands/generate.py +5 -0
  213. django_cfg/management/commands/list_urls.py +7 -2
  214. django_cfg/management/commands/migrate_all.py +6 -2
  215. django_cfg/management/commands/migrator.py +6 -1
  216. django_cfg/management/commands/rundramatiq.py +6 -1
  217. django_cfg/management/commands/rundramatiq_simulator.py +11 -4
  218. django_cfg/management/commands/runserver_ngrok.py +9 -7
  219. django_cfg/management/commands/script.py +25 -21
  220. django_cfg/management/commands/show_config.py +6 -1
  221. django_cfg/management/commands/show_urls.py +8 -3
  222. django_cfg/management/commands/superuser.py +5 -4
  223. django_cfg/management/commands/task_clear.py +8 -3
  224. django_cfg/management/commands/task_status.py +8 -3
  225. django_cfg/management/commands/test_email.py +6 -1
  226. django_cfg/management/commands/test_telegram.py +6 -1
  227. django_cfg/management/commands/test_twilio.py +6 -1
  228. django_cfg/management/commands/tree.py +7 -4
  229. django_cfg/models/__init__.py +88 -3
  230. django_cfg/models/api/__init__.py +27 -0
  231. django_cfg/models/{api.py → api/config.py} +1 -1
  232. django_cfg/models/api/drf/__init__.py +21 -0
  233. django_cfg/models/api/drf/config.py +101 -0
  234. django_cfg/models/api/drf/redoc.py +31 -0
  235. django_cfg/models/api/drf/spectacular.py +129 -0
  236. django_cfg/models/api/drf/swagger.py +59 -0
  237. django_cfg/models/{api_keys.py → api/keys.py} +16 -6
  238. django_cfg/models/{limits.py → api/limits.py} +0 -1
  239. django_cfg/models/base/__init__.py +14 -0
  240. django_cfg/models/django/__init__.py +16 -0
  241. django_cfg/models/{constance.py → django/constance.py} +1 -1
  242. django_cfg/models/{environment.py → django/environment.py} +1 -1
  243. django_cfg/models/infrastructure/__init__.py +17 -0
  244. django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
  245. django_cfg/models/infrastructure/database/__init__.py +22 -0
  246. django_cfg/models/infrastructure/database/config.py +265 -0
  247. django_cfg/models/infrastructure/database/converters.py +91 -0
  248. django_cfg/models/infrastructure/database/parsers.py +96 -0
  249. django_cfg/models/infrastructure/database/routing.py +85 -0
  250. django_cfg/models/infrastructure/database/validators.py +170 -0
  251. django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
  252. django_cfg/models/{security.py → infrastructure/security.py} +2 -2
  253. django_cfg/models/ngrok/__init__.py +11 -0
  254. django_cfg/models/ngrok/auth.py +37 -0
  255. django_cfg/models/ngrok/config.py +77 -0
  256. django_cfg/models/ngrok/tunnel.py +35 -0
  257. django_cfg/models/payments/__init__.py +20 -0
  258. django_cfg/models/payments/api_keys.py +57 -0
  259. django_cfg/models/{payments.py → payments/config.py} +56 -154
  260. django_cfg/models/payments/providers/__init__.py +15 -0
  261. django_cfg/models/payments/providers/base.py +25 -0
  262. django_cfg/models/payments/providers/nowpayments.py +48 -0
  263. django_cfg/models/services/__init__.py +18 -0
  264. django_cfg/models/services/base.py +65 -0
  265. django_cfg/models/{email.py → services/email.py} +1 -1
  266. django_cfg/models/services/telegram.py +172 -0
  267. django_cfg/models/tasks/__init__.py +51 -0
  268. django_cfg/models/tasks/backends.py +250 -0
  269. django_cfg/models/tasks/config.py +314 -0
  270. django_cfg/models/tasks/utils.py +174 -0
  271. django_cfg/modules/base.py +18 -3
  272. django_cfg/modules/django_admin/decorators/actions.py +1 -1
  273. django_cfg/modules/django_admin/decorators/display.py +1 -1
  274. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
  275. django_cfg/modules/django_currency/examples/__init__.py +3 -0
  276. django_cfg/modules/django_currency/examples/example_database_usage.py +144 -0
  277. django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
  278. django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
  279. django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
  280. django_cfg/modules/django_drf_theme/README.md +207 -0
  281. django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
  282. django_cfg/modules/django_drf_theme/__init__.py +23 -0
  283. django_cfg/modules/django_drf_theme/apps.py +15 -0
  284. django_cfg/modules/django_drf_theme/renderers.py +58 -0
  285. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
  286. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
  287. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
  288. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
  289. django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
  290. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
  291. django_cfg/modules/django_email/__init__.py +14 -0
  292. django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
  293. django_cfg/modules/django_email/utils.py +40 -0
  294. django_cfg/modules/django_health/__init__.py +9 -0
  295. django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
  296. django_cfg/modules/django_ipc_client/README.md +346 -0
  297. django_cfg/modules/django_ipc_client/__init__.py +51 -0
  298. django_cfg/modules/django_ipc_client/client.py +540 -0
  299. django_cfg/modules/django_ipc_client/config.py +207 -0
  300. django_cfg/modules/django_ipc_client/dashboard/README.md +517 -0
  301. django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
  302. django_cfg/modules/django_ipc_client/dashboard/__init__.py +11 -0
  303. django_cfg/modules/django_ipc_client/dashboard/apps.py +22 -0
  304. django_cfg/modules/django_ipc_client/dashboard/monitor.py +435 -0
  305. django_cfg/modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js +373 -0
  306. django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/base.html +76 -0
  307. django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +200 -0
  308. django_cfg/modules/django_ipc_client/dashboard/urls.py +22 -0
  309. django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +9 -0
  310. django_cfg/modules/django_ipc_client/dashboard/views.py +251 -0
  311. django_cfg/modules/django_ipc_client/exceptions.py +201 -0
  312. django_cfg/modules/django_llm/llm/client.py +155 -550
  313. django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
  314. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
  315. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
  316. django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
  317. django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
  318. django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
  319. django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
  320. django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
  321. django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
  322. django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
  323. django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
  324. django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
  325. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
  326. django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
  327. django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
  328. django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
  329. django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
  330. django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
  331. django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
  332. django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
  333. django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
  334. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
  335. django_cfg/modules/django_llm/translator/translator.py +150 -603
  336. django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
  337. django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
  338. django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
  339. django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
  340. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
  341. django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
  342. django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
  343. django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
  344. django_cfg/modules/django_logging/__init__.py +14 -0
  345. django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
  346. django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
  347. django_cfg/modules/django_ngrok/__init__.py +39 -0
  348. django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
  349. django_cfg/modules/django_rpc_old/POETRY.md +344 -0
  350. django_cfg/modules/django_rpc_old/README.md +397 -0
  351. django_cfg/modules/django_rpc_old/TESTING.md +358 -0
  352. django_cfg/modules/django_rpc_old/__init__.py +39 -0
  353. django_cfg/modules/django_rpc_old/client.py +531 -0
  354. django_cfg/modules/django_rpc_old/config.py +279 -0
  355. django_cfg/modules/django_rpc_old/exceptions.py +172 -0
  356. django_cfg/modules/django_tailwind/README.md +478 -0
  357. django_cfg/modules/django_tailwind/__init__.py +7 -0
  358. django_cfg/modules/django_tailwind/apps.py +10 -0
  359. django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
  360. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
  361. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
  362. django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
  363. django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
  364. django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
  365. django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
  366. django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
  367. django_cfg/modules/django_tasks/__init__.py +29 -0
  368. django_cfg/modules/django_tasks/factory.py +127 -0
  369. django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
  370. django_cfg/modules/django_tasks/settings.py +107 -0
  371. django_cfg/modules/django_telegram/__init__.py +29 -0
  372. django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
  373. django_cfg/modules/django_telegram/utils.py +62 -0
  374. django_cfg/modules/django_twilio/__init__.py +54 -107
  375. django_cfg/modules/django_twilio/_imports.py +30 -0
  376. django_cfg/modules/django_twilio/base.py +192 -0
  377. django_cfg/modules/django_twilio/email_otp.py +227 -0
  378. django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
  379. django_cfg/modules/django_twilio/simple_service.py +1 -2
  380. django_cfg/modules/django_twilio/sms.py +94 -0
  381. django_cfg/modules/django_twilio/twilio_service.py +2 -3
  382. django_cfg/modules/django_twilio/unified.py +310 -0
  383. django_cfg/modules/django_twilio/utils.py +190 -0
  384. django_cfg/modules/django_twilio/whatsapp.py +137 -0
  385. django_cfg/modules/django_unfold/callbacks/base.py +198 -7
  386. django_cfg/modules/django_unfold/callbacks/main.py +102 -10
  387. django_cfg/modules/django_unfold/dashboard.py +65 -43
  388. django_cfg/modules/django_unfold/models/config.py +13 -12
  389. django_cfg/modules/django_unfold/models/navigation.py +8 -3
  390. django_cfg/modules/django_unfold/models/tabs.py +2 -2
  391. django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
  392. django_cfg/registry/core.py +24 -26
  393. django_cfg/registry/modules.py +5 -2
  394. django_cfg/registry/services.py +20 -3
  395. django_cfg/registry/third_party.py +8 -8
  396. django_cfg/static/admin/css/dashboard.css +260 -0
  397. django_cfg/static/admin/js/commands.js +171 -0
  398. django_cfg/static/admin/js/dashboard.js +126 -0
  399. django_cfg/templates/admin/components/management_commands.js +375 -0
  400. django_cfg/templates/admin/components/progress_bar.html +18 -23
  401. django_cfg/templates/admin/examples/component_class_example.html +156 -0
  402. django_cfg/templates/admin/index.html +48 -20
  403. django_cfg/templates/admin/index_new.html +106 -0
  404. django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
  405. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
  406. django_cfg/templates/admin/sections/commands_section.html +626 -0
  407. django_cfg/templates/admin/sections/overview_section.html +112 -0
  408. django_cfg/templates/admin/sections/stats_section.html +35 -0
  409. django_cfg/templates/admin/sections/system_section.html +99 -0
  410. django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
  411. django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
  412. django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
  413. django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
  414. django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
  415. django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
  416. django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
  417. django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
  418. django_cfg/templatetags/django_cfg.py +7 -1
  419. django_cfg/utils/smart_defaults.py +4 -4
  420. django_cfg-1.4.3.dist-info/METADATA +533 -0
  421. {django_cfg-1.3.13.dist-info → django_cfg-1.4.3.dist-info}/RECORD +432 -195
  422. django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
  423. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
  424. django_cfg/core/generation.py +0 -621
  425. django_cfg/management/commands/validate_config.py +0 -189
  426. django_cfg/models/database.py +0 -480
  427. django_cfg/models/drf.py +0 -272
  428. django_cfg/models/ngrok.py +0 -122
  429. django_cfg/models/services.py +0 -440
  430. django_cfg/models/tasks.py +0 -550
  431. django_cfg/modules/django_twilio/service.py +0 -942
  432. django_cfg/template_archive/django_sample.zip +0 -0
  433. django_cfg/templates/rest_framework/api.html +0 -12
  434. django_cfg/utils/toolkit.py +0 -703
  435. django_cfg-1.3.13.dist-info/METADATA +0 -1029
  436. /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
  437. /django_cfg/core/{environment.py → environment/detector.py} +0 -0
  438. /django_cfg/models/{cors.py → api/cors.py} +0 -0
  439. /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
  440. /django_cfg/models/{base.py → base/config.py} +0 -0
  441. /django_cfg/models/{cfg.py → base/module.py} +0 -0
  442. /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
  443. /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
  444. {django_cfg-1.3.13.dist-info → django_cfg-1.4.3.dist-info}/WHEEL +0 -0
  445. {django_cfg-1.3.13.dist-info → django_cfg-1.4.3.dist-info}/entry_points.txt +0 -0
  446. {django_cfg-1.3.13.dist-info → django_cfg-1.4.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,308 @@
1
+ """
2
+ Dashboard Component Classes
3
+
4
+ Uses Unfold's Component Class system for data preprocessing.
5
+ Separates business logic from presentation templates.
6
+ """
7
+
8
+ from typing import Dict, Any
9
+ from unfold.components import BaseComponent, register_component
10
+
11
+
12
+ @register_component
13
+ class SystemMetricsComponent(BaseComponent):
14
+ """
15
+ System metrics component for dashboard.
16
+
17
+ Provides health metrics for database, cache, storage, and API.
18
+ """
19
+
20
+ def get_context_data(self, **kwargs):
21
+ """Prepare system metrics data."""
22
+ context = super().get_context_data(**kwargs)
23
+ context.update({
24
+ "data": self.get_system_metrics()
25
+ })
26
+ return context
27
+
28
+ def get_system_metrics(self) -> Dict[str, Any]:
29
+ """Fetch system health metrics."""
30
+ from django.db import connection
31
+ from django.core.cache import cache
32
+ import shutil
33
+
34
+ metrics = {}
35
+
36
+ # Database Health
37
+ try:
38
+ with connection.cursor() as cursor:
39
+ cursor.execute("SELECT 1")
40
+ metrics["database"] = {
41
+ "value": 95,
42
+ "title": "Database Health",
43
+ "description": "Connection successful",
44
+ }
45
+ except Exception as e:
46
+ metrics["database"] = {
47
+ "value": 0,
48
+ "title": "Database Health",
49
+ "description": f"Error: {str(e)[:50]}",
50
+ }
51
+
52
+ # Cache Performance
53
+ try:
54
+ cache.set("health_check", "ok", 10)
55
+ if cache.get("health_check") == "ok":
56
+ metrics["cache"] = {
57
+ "value": 90,
58
+ "title": "Cache Performance",
59
+ "description": "Cache working properly",
60
+ }
61
+ else:
62
+ metrics["cache"] = {
63
+ "value": 50,
64
+ "title": "Cache Performance",
65
+ "description": "Cache response delayed",
66
+ }
67
+ except Exception as e:
68
+ metrics["cache"] = {
69
+ "value": 0,
70
+ "title": "Cache Performance",
71
+ "description": f"Error: {str(e)[:50]}",
72
+ }
73
+
74
+ # Storage Space
75
+ try:
76
+ total, used, free = shutil.disk_usage("/")
77
+ free_percentage = int((free / total) * 100)
78
+ usage_percentage = 100 - free_percentage
79
+
80
+ metrics["storage"] = {
81
+ "value": free_percentage,
82
+ "title": "Disk Space",
83
+ "description": f"{free_percentage}% free ({usage_percentage}% used)",
84
+ }
85
+ except Exception as e:
86
+ metrics["storage"] = {
87
+ "value": 0,
88
+ "title": "Disk Space",
89
+ "description": f"Error: {str(e)[:50]}",
90
+ }
91
+
92
+ # API Health
93
+ try:
94
+ from django.urls import get_resolver
95
+ resolver = get_resolver()
96
+ url_patterns = list(resolver.url_patterns)
97
+
98
+ metrics["api"] = {
99
+ "value": 100,
100
+ "title": "REST API",
101
+ "description": f"{len(url_patterns)} URL patterns",
102
+ }
103
+ except Exception as e:
104
+ metrics["api"] = {
105
+ "value": 50,
106
+ "title": "REST API",
107
+ "description": "Unable to count URLs",
108
+ }
109
+
110
+ return metrics
111
+
112
+
113
+ @register_component
114
+ class RecentUsersComponent(BaseComponent):
115
+ """
116
+ Recent users table component.
117
+
118
+ Provides formatted table data for displaying recent user registrations.
119
+ """
120
+
121
+ def get_context_data(self, **kwargs):
122
+ """Prepare recent users table data."""
123
+ context = super().get_context_data(**kwargs)
124
+
125
+ from django.contrib.auth import get_user_model
126
+ User = get_user_model()
127
+
128
+ try:
129
+ recent_users = User.objects.order_by('-date_joined')[:10]
130
+
131
+ context.update({
132
+ "data": {
133
+ "headers": ["Username", "Email", "Status", "Staff", "Joined"],
134
+ "rows": [
135
+ [
136
+ user.username,
137
+ user.email,
138
+ "✅ Active" if user.is_active else "❌ Inactive",
139
+ "🛡️ Yes" if user.is_staff else "—",
140
+ user.date_joined.strftime('%Y-%m-%d %H:%M')
141
+ ]
142
+ for user in recent_users
143
+ ]
144
+ }
145
+ })
146
+ except Exception:
147
+ context.update({
148
+ "data": {
149
+ "headers": [],
150
+ "rows": []
151
+ }
152
+ })
153
+
154
+ return context
155
+
156
+
157
+ @register_component
158
+ class ChartsComponent(BaseComponent):
159
+ """
160
+ Charts data component for analytics.
161
+
162
+ Provides chart data for user registrations and activity.
163
+ Supports time range filtering (7/30/90 days).
164
+ """
165
+
166
+ def get_context_data(self, **kwargs):
167
+ """Prepare charts data."""
168
+ context = super().get_context_data(**kwargs)
169
+
170
+ # Get time range from kwargs (default: 7 days)
171
+ days = kwargs.get('days', 7)
172
+
173
+ from django.contrib.auth import get_user_model
174
+ from datetime import datetime, timedelta
175
+ from django.utils import timezone
176
+ import json
177
+
178
+ User = get_user_model()
179
+
180
+ try:
181
+ # Get last N days
182
+ today = timezone.now().date()
183
+ dates = [(today - timedelta(days=i)).strftime('%Y-%m-%d')
184
+ for i in range(days-1, -1, -1)]
185
+
186
+ # User registrations
187
+ registrations = []
188
+ for date_str in dates:
189
+ date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
190
+ count = User.objects.filter(date_joined__date=date_obj).count()
191
+ registrations.append(count)
192
+
193
+ # User activity (last login)
194
+ activity = []
195
+ for date_str in dates:
196
+ date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
197
+ count = User.objects.filter(
198
+ last_login__date=date_obj
199
+ ).count() if hasattr(User, 'last_login') else 0
200
+ activity.append(count)
201
+
202
+ # Format labels
203
+ day_labels = [d.split('-')[2] for d in dates]
204
+
205
+ # Chart data structures
206
+ user_reg_data = {
207
+ 'labels': day_labels,
208
+ 'datasets': [{
209
+ 'label': 'New Users',
210
+ 'data': registrations,
211
+ 'backgroundColor': 'rgba(59, 130, 246, 0.5)',
212
+ 'borderColor': 'rgb(59, 130, 246)',
213
+ 'borderWidth': 2,
214
+ }]
215
+ }
216
+
217
+ user_activity_data = {
218
+ 'labels': day_labels,
219
+ 'datasets': [{
220
+ 'label': 'Active Users',
221
+ 'data': activity,
222
+ 'backgroundColor': 'rgba(34, 197, 94, 0.5)',
223
+ 'borderColor': 'rgb(34, 197, 94)',
224
+ 'borderWidth': 2,
225
+ }]
226
+ }
227
+
228
+ context.update({
229
+ "data": {
230
+ "registrations": json.dumps(user_reg_data),
231
+ "activity": json.dumps(user_activity_data),
232
+ }
233
+ })
234
+ except Exception:
235
+ context.update({
236
+ "data": {}
237
+ })
238
+
239
+ return context
240
+
241
+
242
+ @register_component
243
+ class ActivityTrackerComponent(BaseComponent):
244
+ """
245
+ Activity tracker component for GitHub-style heatmap.
246
+
247
+ Provides 365 days of user activity data with level indicators.
248
+ """
249
+
250
+ def get_context_data(self, **kwargs):
251
+ """Prepare activity tracker data."""
252
+ context = super().get_context_data(**kwargs)
253
+
254
+ from django.contrib.auth import get_user_model
255
+ from datetime import timedelta
256
+ from django.utils import timezone
257
+
258
+ User = get_user_model()
259
+
260
+ try:
261
+ today = timezone.now().date()
262
+ activity_data = []
263
+
264
+ for days_ago in range(364, -1, -1): # 365 days
265
+ date = today - timedelta(days=days_ago)
266
+
267
+ # Count registrations
268
+ registrations = User.objects.filter(
269
+ date_joined__date=date
270
+ ).count()
271
+
272
+ # Count logins
273
+ logins = 0
274
+ if hasattr(User, 'last_login'):
275
+ logins = User.objects.filter(
276
+ last_login__date=date
277
+ ).count()
278
+
279
+ total_activity = registrations + logins
280
+
281
+ activity_data.append({
282
+ 'date': date.isoformat(),
283
+ 'count': total_activity,
284
+ 'level': self._get_activity_level(total_activity),
285
+ })
286
+
287
+ context.update({
288
+ "data": activity_data
289
+ })
290
+ except Exception:
291
+ context.update({
292
+ "data": []
293
+ })
294
+
295
+ return context
296
+
297
+ def _get_activity_level(self, count: int) -> int:
298
+ """Convert activity count to level (0-4) for heatmap colors."""
299
+ if count == 0:
300
+ return 0
301
+ elif count <= 2:
302
+ return 1
303
+ elif count <= 5:
304
+ return 2
305
+ elif count <= 10:
306
+ return 3
307
+ else:
308
+ return 4
@@ -0,0 +1,176 @@
1
+ """
2
+ Debug utilities for dashboard rendering.
3
+
4
+ Saves rendered HTML to disk for inspection and comparison.
5
+ """
6
+
7
+ import os
8
+ import json
9
+ from datetime import datetime
10
+ from pathlib import Path
11
+ from typing import Optional, Dict, Any
12
+ from django.conf import settings
13
+
14
+
15
+ class DashboardDebugger:
16
+ """Save dashboard renders for debugging."""
17
+
18
+ def __init__(self, output_dir: Optional[Path] = None):
19
+ """
20
+ Initialize debugger.
21
+
22
+ Args:
23
+ output_dir: Directory to save renders (default: django_cfg/debug/dashboard/)
24
+ """
25
+ if output_dir is None:
26
+ # Use django_cfg package directory
27
+ django_cfg_root = Path(__file__).parent.parent
28
+ output_dir = django_cfg_root / 'debug' / 'dashboard'
29
+
30
+ self.output_dir = Path(output_dir)
31
+ self.output_dir.mkdir(parents=True, exist_ok=True)
32
+
33
+ def save_render(
34
+ self,
35
+ html: str,
36
+ name: str = 'dashboard',
37
+ context: Optional[Dict[str, Any]] = None,
38
+ metadata: Optional[Dict[str, Any]] = None
39
+ ) -> Path:
40
+ """
41
+ Save rendered HTML with metadata.
42
+
43
+ Args:
44
+ html: Rendered HTML content
45
+ name: Base name for files
46
+ context: Template context data
47
+ metadata: Additional metadata
48
+
49
+ Returns:
50
+ Path to saved HTML file
51
+ """
52
+ timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
53
+ base_name = f"{name}_{timestamp}"
54
+
55
+ # Save HTML
56
+ html_path = self.output_dir / f"{base_name}.html"
57
+ html_path.write_text(html, encoding='utf-8')
58
+
59
+ # Save context as JSON
60
+ if context:
61
+ context_path = self.output_dir / f"{base_name}_context.json"
62
+ # Convert context to JSON-serializable format
63
+ serializable_context = self._make_serializable(context)
64
+ context_path.write_text(
65
+ json.dumps(serializable_context, indent=2, ensure_ascii=False),
66
+ encoding='utf-8'
67
+ )
68
+
69
+ # Save metadata
70
+ meta = {
71
+ 'timestamp': timestamp,
72
+ 'name': name,
73
+ 'html_size': len(html),
74
+ 'html_lines': html.count('\n'),
75
+ }
76
+
77
+ if metadata:
78
+ meta.update(metadata)
79
+
80
+ meta_path = self.output_dir / f"{base_name}_meta.json"
81
+ meta_path.write_text(
82
+ json.dumps(meta, indent=2, ensure_ascii=False),
83
+ encoding='utf-8'
84
+ )
85
+
86
+ print(f"✅ Saved dashboard render: {html_path}")
87
+ print(f" Context: {context_path if context else 'N/A'}")
88
+ print(f" Metadata: {meta_path}")
89
+
90
+ return html_path
91
+
92
+ def _make_serializable(self, obj: Any) -> Any:
93
+ """Convert object to JSON-serializable format."""
94
+ if isinstance(obj, dict):
95
+ return {k: self._make_serializable(v) for k, v in obj.items()}
96
+ elif isinstance(obj, (list, tuple)):
97
+ return [self._make_serializable(item) for item in obj]
98
+ elif isinstance(obj, (str, int, float, bool, type(None))):
99
+ return obj
100
+ else:
101
+ # For non-serializable objects, use string representation
102
+ return str(obj)
103
+
104
+ def save_section_render(
105
+ self,
106
+ section_name: str,
107
+ html: str,
108
+ section_data: Optional[Dict[str, Any]] = None
109
+ ) -> Path:
110
+ """
111
+ Save individual section render.
112
+
113
+ Args:
114
+ section_name: Name of section (overview, stats, etc.)
115
+ html: Rendered HTML
116
+ section_data: Section-specific data
117
+
118
+ Returns:
119
+ Path to saved file
120
+ """
121
+ return self.save_render(
122
+ html=html,
123
+ name=f"section_{section_name}",
124
+ context=section_data,
125
+ metadata={'section': section_name}
126
+ )
127
+
128
+ def compare_with_archive(self, current_html: str, archive_path: Path) -> Dict[str, Any]:
129
+ """
130
+ Compare current render with archived version.
131
+
132
+ Args:
133
+ current_html: Current rendered HTML
134
+ archive_path: Path to archived HTML
135
+
136
+ Returns:
137
+ Comparison results
138
+ """
139
+ if not archive_path.exists():
140
+ return {
141
+ 'error': f"Archive not found: {archive_path}"
142
+ }
143
+
144
+ archive_html = archive_path.read_text(encoding='utf-8')
145
+
146
+ return {
147
+ 'current_size': len(current_html),
148
+ 'archive_size': len(archive_html),
149
+ 'size_diff': len(current_html) - len(archive_html),
150
+ 'current_lines': current_html.count('\n'),
151
+ 'archive_lines': archive_html.count('\n'),
152
+ 'lines_diff': current_html.count('\n') - archive_html.count('\n'),
153
+ 'identical': current_html == archive_html,
154
+ }
155
+
156
+
157
+ # Global instance
158
+ _debugger: Optional[DashboardDebugger] = None
159
+
160
+
161
+ def get_debugger() -> DashboardDebugger:
162
+ """Get or create global debugger instance."""
163
+ global _debugger
164
+ if _debugger is None:
165
+ _debugger = DashboardDebugger()
166
+ return _debugger
167
+
168
+
169
+ def save_dashboard_render(html: str, **kwargs) -> Path:
170
+ """Convenience function to save dashboard render."""
171
+ return get_debugger().save_render(html, **kwargs)
172
+
173
+
174
+ def save_section_render(section_name: str, html: str, **kwargs) -> Path:
175
+ """Convenience function to save section render."""
176
+ return get_debugger().save_section_render(section_name, html, **kwargs)
File without changes
File without changes
@@ -0,0 +1,109 @@
1
+ """
2
+ Management command to debug dashboard rendering.
3
+
4
+ Renders all dashboard sections and saves them for inspection.
5
+ """
6
+
7
+ from django.core.management.base import BaseCommand
8
+ from django.test import RequestFactory
9
+ from django.contrib.auth import get_user_model
10
+
11
+ from django_cfg.dashboard.sections.overview import OverviewSection
12
+ from django_cfg.dashboard.sections.stats import StatsSection
13
+ from django_cfg.dashboard.sections.system import SystemSection
14
+ from django_cfg.dashboard.sections.commands import CommandsSection
15
+ from django_cfg.dashboard.debug import get_debugger
16
+
17
+
18
+ class Command(BaseCommand):
19
+ help = "Debug dashboard rendering - saves all sections to disk"
20
+
21
+ def add_arguments(self, parser):
22
+ parser.add_argument(
23
+ '--section',
24
+ type=str,
25
+ choices=['overview', 'stats', 'system', 'commands', 'all'],
26
+ default='all',
27
+ help='Which section to render (default: all)'
28
+ )
29
+ parser.add_argument(
30
+ '--user',
31
+ type=str,
32
+ help='Username to use for request (default: first superuser)'
33
+ )
34
+
35
+ def handle(self, *args, **options):
36
+ # Create mock request
37
+ factory = RequestFactory()
38
+ request = factory.get('/admin/')
39
+
40
+ # Get user for request
41
+ User = get_user_model()
42
+ username = options.get('user')
43
+
44
+ if username:
45
+ try:
46
+ user = User.objects.get(username=username)
47
+ except User.DoesNotExist:
48
+ self.stdout.write(
49
+ self.style.ERROR(f"User '{username}' not found")
50
+ )
51
+ return
52
+ else:
53
+ # Use first superuser
54
+ user = User.objects.filter(is_superuser=True).first()
55
+ if not user:
56
+ self.stdout.write(
57
+ self.style.WARNING("No superuser found, using anonymous request")
58
+ )
59
+
60
+ if user:
61
+ request.user = user
62
+ self.stdout.write(f"Using user: {user.username}")
63
+
64
+ # Get debugger
65
+ debugger = get_debugger()
66
+ self.stdout.write(f"Saving renders to: {debugger.output_dir}")
67
+
68
+ section_choice = options['section']
69
+ sections = {
70
+ 'overview': OverviewSection,
71
+ 'stats': StatsSection,
72
+ 'system': SystemSection,
73
+ 'commands': CommandsSection,
74
+ }
75
+
76
+ if section_choice == 'all':
77
+ sections_to_render = sections.items()
78
+ else:
79
+ sections_to_render = [(section_choice, sections[section_choice])]
80
+
81
+ # Render sections
82
+ for name, SectionClass in sections_to_render:
83
+ self.stdout.write(f"\nRendering {name} section...")
84
+
85
+ try:
86
+ section = SectionClass(request)
87
+ html = section.render()
88
+
89
+ # Save render
90
+ path = debugger.save_section_render(
91
+ section_name=name,
92
+ html=html,
93
+ section_data=section.get_context_data() if hasattr(section, 'get_context_data') else None
94
+ )
95
+
96
+ self.stdout.write(
97
+ self.style.SUCCESS(f"✅ {name}: {len(html)} bytes, saved to {path.name}")
98
+ )
99
+
100
+ except Exception as e:
101
+ self.stdout.write(
102
+ self.style.ERROR(f"❌ {name}: {e}")
103
+ )
104
+ import traceback
105
+ traceback.print_exc()
106
+
107
+ self.stdout.write(
108
+ self.style.SUCCESS(f"\n✅ Done! Check renders in: {debugger.output_dir}")
109
+ )
@@ -0,0 +1 @@
1
+ """Dashboard sections package."""