django-cfg 1.4.21__py3-none-any.whl → 1.4.23__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.
- django_cfg/__init__.py +4 -4
- django_cfg/apps/accounts/__init__.py +1 -1
- django_cfg/apps/accounts/__models.py +30 -29
- django_cfg/apps/accounts/admin/__init__.py +14 -3
- django_cfg/apps/accounts/admin/activity_admin.py +19 -19
- django_cfg/apps/accounts/admin/filters.py +7 -6
- django_cfg/apps/accounts/admin/group_admin.py +10 -16
- django_cfg/apps/accounts/admin/inlines.py +21 -19
- django_cfg/apps/accounts/admin/otp_admin.py +12 -12
- django_cfg/apps/accounts/admin/registration_admin.py +24 -24
- django_cfg/apps/accounts/admin/resources.py +49 -48
- django_cfg/apps/accounts/admin/twilio_admin.py +37 -37
- django_cfg/apps/accounts/admin/user_admin.py +45 -41
- django_cfg/apps/accounts/management/commands/otp_test.py +11 -11
- django_cfg/apps/accounts/managers/__init__.py +1 -1
- django_cfg/apps/accounts/managers/user_manager.py +6 -7
- django_cfg/apps/accounts/migrations/0001_initial.py +3 -2
- django_cfg/apps/accounts/models/__init__.py +15 -16
- django_cfg/apps/accounts/models/activity.py +5 -5
- django_cfg/apps/accounts/models/integrations.py +15 -15
- django_cfg/apps/accounts/models/registration.py +3 -2
- django_cfg/apps/accounts/models/user.py +3 -2
- django_cfg/apps/accounts/serializers/__init__.py +10 -3
- django_cfg/apps/accounts/serializers/otp.py +5 -4
- django_cfg/apps/accounts/serializers/profile.py +4 -5
- django_cfg/apps/accounts/serializers/webhook.py +13 -13
- django_cfg/apps/accounts/services/activity_service.py +13 -12
- django_cfg/apps/accounts/services/otp_service.py +16 -14
- django_cfg/apps/accounts/signals.py +18 -16
- django_cfg/apps/accounts/urls.py +10 -5
- django_cfg/apps/accounts/utils/notifications.py +22 -22
- django_cfg/apps/accounts/views/__init__.py +1 -1
- django_cfg/apps/accounts/views/otp.py +15 -14
- django_cfg/apps/accounts/views/profile.py +14 -10
- django_cfg/apps/accounts/views/webhook.py +46 -48
- django_cfg/apps/agents/__init__.py +3 -3
- django_cfg/apps/agents/admin/__init__.py +1 -1
- django_cfg/apps/agents/admin/execution_admin.py +68 -72
- django_cfg/apps/agents/admin/registry_admin.py +50 -54
- django_cfg/apps/agents/admin/toolsets_admin.py +63 -67
- django_cfg/apps/agents/apps.py +3 -3
- django_cfg/apps/agents/core/__init__.py +4 -4
- django_cfg/apps/agents/core/dependencies.py +24 -23
- django_cfg/apps/agents/core/django_agent.py +41 -39
- django_cfg/apps/agents/core/exceptions.py +12 -12
- django_cfg/apps/agents/core/models.py +16 -15
- django_cfg/apps/agents/core/orchestrator.py +58 -58
- django_cfg/apps/agents/examples/simple_example.py +24 -19
- django_cfg/apps/agents/integration/__init__.py +1 -1
- django_cfg/apps/agents/integration/middleware.py +12 -11
- django_cfg/apps/agents/integration/registry.py +52 -49
- django_cfg/apps/agents/integration/signals.py +5 -5
- django_cfg/apps/agents/management/commands/create_agent.py +39 -38
- django_cfg/apps/agents/management/commands/orchestrator_status.py +40 -39
- django_cfg/apps/agents/managers/__init__.py +8 -3
- django_cfg/apps/agents/managers/execution.py +42 -41
- django_cfg/apps/agents/managers/registry.py +40 -39
- django_cfg/apps/agents/managers/toolsets.py +87 -86
- django_cfg/apps/agents/migrations/0001_initial.py +2 -1
- django_cfg/apps/agents/models/__init__.py +2 -2
- django_cfg/apps/agents/models/execution.py +43 -42
- django_cfg/apps/agents/models/registry.py +46 -45
- django_cfg/apps/agents/models/toolsets.py +63 -62
- django_cfg/apps/agents/patterns/__init__.py +5 -5
- django_cfg/apps/agents/patterns/content_agents.py +17 -16
- django_cfg/apps/agents/toolsets/__init__.py +3 -3
- django_cfg/apps/agents/toolsets/cache_toolset.py +56 -55
- django_cfg/apps/agents/toolsets/django_toolset.py +43 -42
- django_cfg/apps/agents/toolsets/file_toolset.py +64 -63
- django_cfg/apps/agents/toolsets/orm_toolset.py +75 -74
- django_cfg/apps/agents/urls.py +3 -2
- django_cfg/apps/api/commands/urls.py +1 -0
- django_cfg/apps/api/commands/views.py +23 -26
- django_cfg/apps/api/endpoints/checker.py +5 -4
- django_cfg/apps/api/endpoints/drf_views.py +2 -2
- django_cfg/apps/api/endpoints/tests.py +6 -5
- django_cfg/apps/api/endpoints/urls.py +2 -1
- django_cfg/apps/api/endpoints/views.py +1 -0
- django_cfg/apps/api/health/drf_views.py +6 -6
- django_cfg/apps/api/health/urls.py +2 -1
- django_cfg/apps/api/health/views.py +41 -41
- django_cfg/{modules/django_ipc_client → apps/ipc}/__init__.py +6 -6
- django_cfg/apps/ipc/apps.py +28 -0
- django_cfg/apps/ipc/serializers/__init__.py +19 -0
- django_cfg/apps/ipc/serializers/serializers.py +229 -0
- django_cfg/apps/ipc/services/__init__.py +7 -0
- django_cfg/apps/ipc/services/client/__init__.py +23 -0
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/client.py +7 -6
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/exceptions.py +1 -1
- django_cfg/{modules/django_ipc_client/dashboard → apps/ipc/services}/monitor.py +23 -5
- django_cfg/{modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js → apps/ipc/static/django_cfg_ipc/js/dashboard.mjs} +131 -63
- django_cfg/{modules/django_ipc_client/dashboard/templates/django_ipc_dashboard → apps/ipc/templates/django_cfg_ipc}/base.html +5 -10
- django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +202 -0
- django_cfg/apps/ipc/urls.py +21 -0
- django_cfg/apps/ipc/urls_admin.py +20 -0
- django_cfg/apps/ipc/views/__init__.py +8 -0
- django_cfg/apps/ipc/views/dashboard.py +15 -0
- django_cfg/apps/ipc/views/viewsets.py +245 -0
- django_cfg/apps/knowbase/admin/__init__.py +2 -2
- django_cfg/apps/knowbase/admin/actions/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +2 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +81 -84
- django_cfg/apps/knowbase/admin/chat_admin.py +70 -72
- django_cfg/apps/knowbase/admin/document_admin.py +10 -11
- django_cfg/apps/knowbase/admin/external_data_admin.py +69 -71
- django_cfg/apps/knowbase/admin/helpers/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/helpers/configs.py +2 -2
- django_cfg/apps/knowbase/admin/helpers/statistics.py +1 -1
- django_cfg/apps/knowbase/apps.py +13 -13
- django_cfg/apps/knowbase/config/__init__.py +7 -6
- django_cfg/apps/knowbase/config/constance_fields.py +14 -12
- django_cfg/apps/knowbase/config/constance_settings.py +32 -31
- django_cfg/apps/knowbase/config/settings.py +28 -28
- django_cfg/apps/knowbase/examples/external_data_usage.py +35 -32
- django_cfg/apps/knowbase/management/commands/knowbase_stats.py +33 -32
- django_cfg/apps/knowbase/management/commands/setup_knowbase.py +11 -13
- django_cfg/apps/knowbase/managers/__init__.py +2 -2
- django_cfg/apps/knowbase/managers/archive.py +86 -85
- django_cfg/apps/knowbase/managers/base.py +5 -5
- django_cfg/apps/knowbase/managers/chat.py +29 -28
- django_cfg/apps/knowbase/managers/document.py +39 -39
- django_cfg/apps/knowbase/managers/external_data.py +74 -73
- django_cfg/apps/knowbase/migrations/0001_initial.py +2 -1
- django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +2 -1
- django_cfg/apps/knowbase/mixins/__init__.py +4 -4
- django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
- django_cfg/apps/knowbase/mixins/config.py +19 -18
- django_cfg/apps/knowbase/mixins/creator.py +7 -7
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
- django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
- django_cfg/apps/knowbase/mixins/service.py +47 -45
- django_cfg/apps/knowbase/models/__init__.py +7 -7
- django_cfg/apps/knowbase/models/archive.py +72 -72
- django_cfg/apps/knowbase/models/base.py +12 -13
- django_cfg/apps/knowbase/models/chat.py +20 -19
- django_cfg/apps/knowbase/models/document.py +37 -35
- django_cfg/apps/knowbase/models/external_data.py +41 -42
- django_cfg/apps/knowbase/serializers/__init__.py +7 -7
- django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
- django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
- django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
- django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
- django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
- django_cfg/apps/knowbase/services/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
- django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
- django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
- django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
- django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
- django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
- django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
- django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
- django_cfg/apps/knowbase/services/base.py +11 -9
- django_cfg/apps/knowbase/services/chat_service.py +40 -39
- django_cfg/apps/knowbase/services/document_service.py +28 -27
- django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
- django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
- django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
- django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
- django_cfg/apps/knowbase/services/embedding/models.py +52 -51
- django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
- django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
- django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
- django_cfg/apps/knowbase/services/search_service.py +52 -49
- django_cfg/apps/knowbase/signals/__init__.py +2 -5
- django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
- django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
- django_cfg/apps/knowbase/signals/document_signals.py +22 -22
- django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
- django_cfg/apps/knowbase/tasks/__init__.py +6 -7
- django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
- django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
- django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
- django_cfg/apps/knowbase/urls.py +3 -2
- django_cfg/apps/knowbase/urls_admin.py +6 -3
- django_cfg/apps/knowbase/urls_system.py +4 -5
- django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
- django_cfg/apps/knowbase/utils/text_processing.py +76 -75
- django_cfg/apps/knowbase/utils/validation.py +9 -9
- django_cfg/apps/knowbase/views/__init__.py +5 -5
- django_cfg/apps/knowbase/views/archive_views.py +90 -87
- django_cfg/apps/knowbase/views/base.py +9 -12
- django_cfg/apps/knowbase/views/chat_views.py +32 -32
- django_cfg/apps/knowbase/views/document_views.py +27 -28
- django_cfg/apps/knowbase/views/public_views.py +19 -19
- django_cfg/apps/leads/admin/leads_admin.py +41 -45
- django_cfg/apps/leads/admin/resources.py +14 -14
- django_cfg/apps/leads/admin.py +7 -9
- django_cfg/apps/leads/apps.py +1 -1
- django_cfg/apps/leads/models.py +17 -17
- django_cfg/apps/leads/serializers.py +5 -4
- django_cfg/apps/leads/signals.py +7 -7
- django_cfg/apps/leads/tests.py +47 -47
- django_cfg/apps/leads/urls.py +2 -2
- django_cfg/apps/leads/views.py +11 -11
- django_cfg/apps/maintenance/__init__.py +3 -3
- django_cfg/apps/maintenance/admin/__init__.py +1 -1
- django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
- django_cfg/apps/maintenance/admin/log_admin.py +35 -37
- django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
- django_cfg/apps/maintenance/admin/site_admin.py +49 -52
- django_cfg/apps/maintenance/apps.py +2 -2
- django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
- django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
- django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
- django_cfg/apps/maintenance/managers/__init__.py +1 -1
- django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
- django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
- django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
- django_cfg/apps/maintenance/models/__init__.py +2 -2
- django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
- django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
- django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
- django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
- django_cfg/apps/maintenance/services/__init__.py +3 -3
- django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
- django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
- django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
- django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
- django_cfg/apps/maintenance/utils/__init__.py +1 -1
- django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
- django_cfg/apps/newsletter/admin/__init__.py +12 -16
- django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
- django_cfg/apps/newsletter/admin/resources.py +29 -29
- django_cfg/apps/newsletter/admin.py +39 -32
- django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
- django_cfg/apps/newsletter/managers/__init__.py +1 -1
- django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
- django_cfg/apps/newsletter/models.py +34 -33
- django_cfg/apps/newsletter/serializers.py +13 -13
- django_cfg/apps/newsletter/services/email_service.py +42 -40
- django_cfg/apps/newsletter/signals.py +4 -3
- django_cfg/apps/newsletter/urls.py +7 -7
- django_cfg/apps/newsletter/views/__init__.py +14 -19
- django_cfg/apps/newsletter/views/campaigns.py +19 -19
- django_cfg/apps/newsletter/views/emails.py +20 -20
- django_cfg/apps/newsletter/views/newsletters.py +5 -5
- django_cfg/apps/newsletter/views/subscriptions.py +24 -24
- django_cfg/apps/newsletter/views/tracking.py +6 -5
- django_cfg/apps/payments/admin/__init__.py +6 -5
- django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
- django_cfg/apps/payments/admin/balance_admin.py +41 -47
- django_cfg/apps/payments/admin/currencies_admin.py +60 -62
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
- django_cfg/apps/payments/admin/filters.py +59 -59
- django_cfg/apps/payments/admin/networks_admin.py +36 -50
- django_cfg/apps/payments/admin/payments_admin.py +47 -49
- django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
- django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
- django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
- django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
- django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
- django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
- django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
- django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
- django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
- django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
- django_cfg/apps/payments/admin_interface/views/base.py +17 -19
- django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
- django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
- django_cfg/apps/payments/apps.py +7 -6
- django_cfg/apps/payments/config/__init__.py +4 -4
- django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
- django_cfg/apps/payments/config/helpers.py +14 -12
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
- django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
- django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
- django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
- django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
- django_cfg/apps/payments/management/commands/test_providers.py +83 -84
- django_cfg/apps/payments/middleware/__init__.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +77 -78
- django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
- django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
- django_cfg/apps/payments/migrations/0001_initial.py +2 -1
- django_cfg/apps/payments/models/__init__.py +11 -12
- django_cfg/apps/payments/models/api_keys.py +29 -27
- django_cfg/apps/payments/models/balance.py +38 -38
- django_cfg/apps/payments/models/base.py +12 -11
- django_cfg/apps/payments/models/currencies.py +53 -52
- django_cfg/apps/payments/models/managers/__init__.py +13 -14
- django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
- django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
- django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
- django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
- django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
- django_cfg/apps/payments/models/payments.py +167 -73
- django_cfg/apps/payments/models/subscriptions.py +56 -54
- django_cfg/apps/payments/models/tariffs.py +35 -34
- django_cfg/apps/payments/services/__init__.py +33 -36
- django_cfg/apps/payments/services/cache/__init__.py +7 -1
- django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
- django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
- django_cfg/apps/payments/services/cache_service/keys.py +8 -8
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
- django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
- django_cfg/apps/payments/services/core/__init__.py +3 -3
- django_cfg/apps/payments/services/core/balance_service.py +69 -65
- django_cfg/apps/payments/services/core/base.py +25 -22
- django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
- django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
- django_cfg/apps/payments/services/core/currency_service.py +68 -66
- django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
- django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
- django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
- django_cfg/apps/payments/services/core/payment_service.py +10 -7
- django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
- django_cfg/apps/payments/services/core/subscription_service.py +77 -74
- django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
- django_cfg/apps/payments/services/core/webhook_service.py +67 -63
- django_cfg/apps/payments/services/integrations/__init__.py +3 -3
- django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
- django_cfg/apps/payments/services/providers/base.py +59 -57
- django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
- django_cfg/apps/payments/services/providers/models/base.py +15 -15
- django_cfg/apps/payments/services/providers/models/providers.py +13 -12
- django_cfg/apps/payments/services/providers/models/universal.py +6 -5
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
- django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
- django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
- django_cfg/apps/payments/services/providers/registry.py +65 -63
- django_cfg/apps/payments/services/providers/sync_service.py +50 -50
- django_cfg/apps/payments/services/types/__init__.py +21 -22
- django_cfg/apps/payments/services/types/data.py +14 -13
- django_cfg/apps/payments/services/types/requests.py +21 -22
- django_cfg/apps/payments/services/types/responses.py +16 -15
- django_cfg/apps/payments/services/types/webhooks.py +30 -30
- django_cfg/apps/payments/signals/__init__.py +4 -6
- django_cfg/apps/payments/signals/api_key_signals.py +33 -32
- django_cfg/apps/payments/signals/balance_signals.py +28 -26
- django_cfg/apps/payments/signals/payment_signals.py +29 -28
- django_cfg/apps/payments/signals/subscription_signals.py +39 -38
- django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
- django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
- django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
- django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
- django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
- django_cfg/apps/payments/tasks/__init__.py +11 -12
- django_cfg/apps/payments/tasks/types.py +10 -9
- django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
- django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
- django_cfg/apps/payments/urls.py +31 -14
- django_cfg/apps/payments/urls_admin.py +10 -10
- django_cfg/apps/payments/views/api/__init__.py +32 -33
- django_cfg/apps/payments/views/api/api_keys.py +62 -62
- django_cfg/apps/payments/views/api/balances.py +63 -64
- django_cfg/apps/payments/views/api/base.py +52 -52
- django_cfg/apps/payments/views/api/currencies.py +75 -63
- django_cfg/apps/payments/views/api/payments.py +73 -74
- django_cfg/apps/payments/views/api/subscriptions.py +71 -72
- django_cfg/apps/payments/views/api/webhooks.py +85 -84
- django_cfg/apps/payments/views/overview/__init__.py +7 -7
- django_cfg/apps/payments/views/overview/serializers.py +13 -14
- django_cfg/apps/payments/views/overview/services.py +66 -67
- django_cfg/apps/payments/views/overview/urls.py +2 -1
- django_cfg/apps/payments/views/overview/views.py +31 -31
- django_cfg/apps/payments/views/serializers/__init__.py +35 -36
- django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
- django_cfg/apps/payments/views/serializers/balances.py +34 -33
- django_cfg/apps/payments/views/serializers/currencies.py +36 -34
- django_cfg/apps/payments/views/serializers/payments.py +48 -47
- django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
- django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
- django_cfg/apps/support/admin/__init__.py +3 -3
- django_cfg/apps/support/admin/resources.py +26 -26
- django_cfg/apps/support/admin/support_admin.py +44 -48
- django_cfg/apps/support/admin.py +16 -15
- django_cfg/apps/support/apps.py +1 -1
- django_cfg/apps/support/managers/message_manager.py +4 -4
- django_cfg/apps/support/managers/ticket_manager.py +13 -12
- django_cfg/apps/support/migrations/0001_initial.py +2 -1
- django_cfg/apps/support/models.py +3 -1
- django_cfg/apps/support/serializers.py +4 -2
- django_cfg/apps/support/signals.py +12 -10
- django_cfg/apps/support/urls.py +4 -3
- django_cfg/apps/support/utils/support_email_service.py +11 -9
- django_cfg/apps/support/views/__init__.py +3 -3
- django_cfg/apps/support/views/admin.py +9 -9
- django_cfg/apps/support/views/api.py +10 -9
- django_cfg/apps/support/views/chat.py +14 -14
- django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
- django_cfg/apps/tasks/apps.py +2 -2
- django_cfg/apps/tasks/serializers.py +6 -6
- django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
- django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
- django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
- django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
- django_cfg/apps/tasks/urls.py +3 -2
- django_cfg/apps/tasks/urls_admin.py +1 -0
- django_cfg/apps/tasks/utils/simulator.py +49 -52
- django_cfg/apps/tasks/views/api.py +75 -73
- django_cfg/apps/tasks/views/dashboard.py +5 -4
- django_cfg/apps/urls.py +20 -11
- django_cfg/apps.py +6 -5
- django_cfg/cli/commands/create_project.py +7 -6
- django_cfg/cli/commands/info.py +25 -25
- django_cfg/cli/utils.py +27 -27
- django_cfg/config.py +1 -1
- django_cfg/core/__init__.py +8 -8
- django_cfg/core/base/config_model.py +13 -12
- django_cfg/core/builders/apps_builder.py +2 -2
- django_cfg/core/builders/middleware_builder.py +1 -1
- django_cfg/core/builders/security_builder.py +1 -1
- django_cfg/core/config.py +2 -2
- django_cfg/core/environment/detector.py +27 -28
- django_cfg/core/exceptions.py +1 -1
- django_cfg/core/generation/core_generators/settings.py +1 -1
- django_cfg/core/generation/core_generators/static.py +11 -5
- django_cfg/core/generation/core_generators/templates.py +1 -1
- django_cfg/core/generation/data_generators/__init__.py +1 -1
- django_cfg/core/generation/data_generators/cache.py +1 -1
- django_cfg/core/generation/data_generators/database.py +1 -1
- django_cfg/core/generation/generation.py +1 -3
- django_cfg/core/generation/integration_generators/__init__.py +2 -2
- django_cfg/core/generation/integration_generators/api.py +12 -2
- django_cfg/core/generation/integration_generators/sessions.py +1 -1
- django_cfg/core/generation/integration_generators/tailwind.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +1 -1
- django_cfg/core/generation/integration_generators/third_party.py +1 -1
- django_cfg/core/generation/orchestrator.py +1 -1
- django_cfg/core/generation/protocols.py +1 -1
- django_cfg/core/generation/utility_generators/__init__.py +1 -1
- django_cfg/core/generation/utility_generators/email.py +1 -1
- django_cfg/core/generation/utility_generators/i18n.py +1 -1
- django_cfg/core/generation/utility_generators/limits.py +1 -1
- django_cfg/core/generation/utility_generators/logging.py +1 -1
- django_cfg/core/generation/utility_generators/security.py +1 -1
- django_cfg/core/generation/utils/helpers.py +1 -1
- django_cfg/core/integration/__init__.py +5 -5
- django_cfg/core/integration/commands_collector.py +38 -39
- django_cfg/core/integration/display/__init__.py +2 -2
- django_cfg/core/integration/display/base.py +30 -30
- django_cfg/core/integration/display/ngrok.py +35 -36
- django_cfg/core/integration/display/startup.py +149 -139
- django_cfg/core/integration/url_integration.py +10 -10
- django_cfg/core/integration/version_checker.py +20 -19
- django_cfg/core/services/config_service.py +4 -4
- django_cfg/core/state/__init__.py +1 -1
- django_cfg/core/state/registry.py +1 -1
- django_cfg/core/types/__init__.py +8 -1
- django_cfg/core/validation.py +36 -39
- django_cfg/management/commands/check_endpoints.py +3 -1
- django_cfg/management/commands/check_settings.py +3 -1
- django_cfg/management/commands/clear_constance.py +3 -1
- django_cfg/management/commands/create_token.py +3 -1
- django_cfg/management/commands/generate_clients.py +3 -1
- django_cfg/management/commands/migrate_all.py +3 -1
- django_cfg/management/commands/rundramatiq.py +3 -1
- django_cfg/management/commands/rundramatiq_simulator.py +3 -1
- django_cfg/management/commands/runserver_ngrok.py +3 -1
- django_cfg/management/commands/show_config.py +3 -1
- django_cfg/management/commands/superuser.py +3 -1
- django_cfg/management/commands/task_clear.py +3 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -1
- django_cfg/management/commands/test_telegram.py +3 -1
- django_cfg/management/commands/test_twilio.py +3 -1
- django_cfg/management/commands/validate_openapi.py +3 -1
- django_cfg/middleware/pagination.py +8 -8
- django_cfg/middleware/public_endpoints.py +24 -23
- django_cfg/middleware/user_activity.py +27 -25
- django_cfg/models/__init__.py +19 -20
- django_cfg/models/api/__init__.py +4 -4
- django_cfg/models/api/config.py +23 -21
- django_cfg/models/api/cors.py +17 -16
- django_cfg/models/api/drf/__init__.py +1 -1
- django_cfg/models/api/drf/config.py +2 -1
- django_cfg/models/api/drf/redoc.py +2 -1
- django_cfg/models/api/drf/spectacular.py +4 -2
- django_cfg/models/api/drf/swagger.py +2 -1
- django_cfg/models/api/jwt.py +37 -36
- django_cfg/models/api/keys.py +13 -12
- django_cfg/models/api/limits.py +31 -30
- django_cfg/models/base/config.py +40 -41
- django_cfg/models/base/module.py +8 -8
- django_cfg/models/django/__init__.py +1 -1
- django_cfg/models/django/constance.py +8 -7
- django_cfg/models/django/environment.py +5 -3
- django_cfg/models/django/openapi.py +6 -16
- django_cfg/models/django/revolution_legacy.py +17 -16
- django_cfg/models/infrastructure/__init__.py +1 -1
- django_cfg/models/infrastructure/cache.py +46 -45
- django_cfg/models/infrastructure/database/config.py +4 -6
- django_cfg/models/infrastructure/database/converters.py +1 -1
- django_cfg/models/infrastructure/database/parsers.py +1 -1
- django_cfg/models/infrastructure/database/validators.py +1 -1
- django_cfg/models/infrastructure/logging.py +59 -57
- django_cfg/models/infrastructure/security.py +26 -24
- django_cfg/models/ngrok/auth.py +2 -1
- django_cfg/models/ngrok/config.py +3 -2
- django_cfg/models/ngrok/tunnel.py +2 -1
- django_cfg/models/payments/__init__.py +1 -1
- django_cfg/models/payments/api_keys.py +3 -1
- django_cfg/models/payments/config.py +4 -1
- django_cfg/models/payments/providers/base.py +2 -1
- django_cfg/models/payments/providers/nowpayments.py +3 -1
- django_cfg/models/services/__init__.py +1 -1
- django_cfg/models/services/base.py +2 -1
- django_cfg/models/services/email.py +28 -26
- django_cfg/models/services/telegram.py +2 -1
- django_cfg/models/tasks/__init__.py +2 -2
- django_cfg/models/tasks/backends.py +4 -3
- django_cfg/models/tasks/config.py +6 -4
- django_cfg/models/tasks/utils.py +3 -3
- django_cfg/modules/base.py +18 -17
- django_cfg/modules/django_admin/__init__.py +14 -15
- django_cfg/modules/django_admin/decorators/__init__.py +1 -1
- django_cfg/modules/django_admin/decorators/actions.py +8 -7
- django_cfg/modules/django_admin/decorators/display.py +9 -7
- django_cfg/modules/django_admin/icons/__init__.py +1 -1
- django_cfg/modules/django_admin/icons/constants.py +27 -27
- django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
- django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
- django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
- django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
- django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
- django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
- django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
- django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
- django_cfg/modules/django_admin/management/commands/script.py +58 -60
- django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
- django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
- django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
- django_cfg/modules/django_admin/management/commands/tree.py +50 -54
- django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
- django_cfg/modules/django_admin/models/__init__.py +4 -4
- django_cfg/modules/django_admin/models/action_models.py +3 -1
- django_cfg/modules/django_admin/models/badge_models.py +4 -2
- django_cfg/modules/django_admin/models/base.py +3 -3
- django_cfg/modules/django_admin/models/display_models.py +1 -0
- django_cfg/modules/django_admin/utils/badges.py +27 -26
- django_cfg/modules/django_admin/utils/displays.py +49 -49
- django_cfg/modules/django_client/apps.py +21 -3
- django_cfg/modules/django_client/core/__init__.py +9 -10
- django_cfg/modules/django_client/core/archive/manager.py +2 -2
- django_cfg/modules/django_client/core/cli/main.py +1 -3
- django_cfg/modules/django_client/core/config/config.py +3 -1
- django_cfg/modules/django_client/core/config/group.py +1 -0
- django_cfg/modules/django_client/core/config/service.py +2 -1
- django_cfg/modules/django_client/core/generator/__init__.py +1 -1
- django_cfg/modules/django_client/core/generator/base.py +2 -2
- django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
- django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
- django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
- django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
- django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
- django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
- django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
- django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
- django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
- django_cfg/modules/django_client/core/groups/__init__.py +1 -1
- django_cfg/modules/django_client/core/groups/detector.py +2 -1
- django_cfg/modules/django_client/core/groups/manager.py +2 -1
- django_cfg/modules/django_client/core/ir/schema.py +1 -1
- django_cfg/modules/django_client/core/parser/base.py +0 -2
- django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
- django_cfg/modules/django_client/core/validation/__init__.py +1 -1
- django_cfg/modules/django_client/core/validation/fixer.py +1 -2
- django_cfg/modules/django_client/core/validation/reporter.py +2 -2
- django_cfg/modules/django_client/core/validation/safety.py +1 -1
- django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
- django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
- django_cfg/modules/django_client/spectacular/__init__.py +1 -1
- django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
- django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
- django_cfg/modules/django_client/spectacular/schema.py +5 -5
- django_cfg/modules/django_client/system/__init__.py +24 -0
- django_cfg/modules/django_client/system/base_generator.py +123 -0
- django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
- django_cfg/modules/django_client/system/mjs_generator.py +219 -0
- django_cfg/modules/django_client/system/schema_parser.py +195 -0
- django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
- django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
- django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
- django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
- django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
- django_cfg/modules/django_client/urls.py +3 -2
- django_cfg/modules/django_currency/__init__.py +17 -18
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
- django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
- django_cfg/modules/django_currency/core/__init__.py +7 -13
- django_cfg/modules/django_currency/core/converter.py +25 -24
- django_cfg/modules/django_currency/core/models.py +9 -8
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +65 -66
- django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
- django_cfg/modules/django_currency/utils/cache.py +10 -11
- django_cfg/modules/django_dashboard/__init__.py +4 -5
- django_cfg/modules/django_dashboard/components.py +11 -7
- django_cfg/modules/django_dashboard/debug.py +1 -3
- django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
- django_cfg/modules/django_dashboard/sections/base.py +2 -1
- django_cfg/modules/django_dashboard/sections/commands.py +3 -2
- django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
- django_cfg/modules/django_dashboard/sections/overview.py +13 -9
- django_cfg/modules/django_dashboard/sections/stats.py +2 -2
- django_cfg/modules/django_dashboard/sections/system.py +2 -1
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
- django_cfg/modules/django_email/management/commands/test_email.py +8 -7
- django_cfg/modules/django_email/service.py +5 -4
- django_cfg/modules/django_health/service.py +46 -44
- django_cfg/modules/django_import_export/__init__.py +7 -3
- django_cfg/modules/django_llm/__init__.py +3 -2
- django_cfg/modules/django_llm/example.py +58 -56
- django_cfg/modules/django_llm/llm/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/cache.py +21 -20
- django_cfg/modules/django_llm/llm/client.py +9 -9
- django_cfg/modules/django_llm/llm/costs.py +14 -14
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/extractor.py +8 -8
- django_cfg/modules/django_llm/llm/models.py +5 -5
- django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
- django_cfg/modules/django_llm/llm/models_cache.py +91 -92
- django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
- django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
- django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
- django_cfg/modules/django_llm/translator/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/cache.py +36 -35
- django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
- django_cfg/modules/django_llm/translator/translator.py +5 -4
- django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
- django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
- django_cfg/modules/django_logging/__init__.py +1 -1
- django_cfg/modules/django_logging/django_logger.py +33 -34
- django_cfg/modules/django_logging/logger.py +3 -7
- django_cfg/modules/django_ngrok/__init__.py +7 -7
- django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
- django_cfg/modules/django_ngrok/service.py +33 -32
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
- django_cfg/modules/django_tasks/__init__.py +5 -5
- django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
- django_cfg/modules/django_tasks/factory.py +1 -1
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
- django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
- django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
- django_cfg/modules/django_tasks/service.py +4 -3
- django_cfg/modules/django_tasks/settings.py +1 -1
- django_cfg/modules/django_telegram/__init__.py +4 -4
- django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
- django_cfg/modules/django_telegram/service.py +4 -3
- django_cfg/modules/django_telegram/utils.py +1 -1
- django_cfg/modules/django_twilio/__init__.py +15 -16
- django_cfg/modules/django_twilio/_imports.py +1 -1
- django_cfg/modules/django_twilio/base.py +9 -5
- django_cfg/modules/django_twilio/email_otp.py +4 -3
- django_cfg/modules/django_twilio/exceptions.py +36 -36
- django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
- django_cfg/modules/django_twilio/models.py +54 -53
- django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
- django_cfg/modules/django_twilio/simple_service.py +42 -41
- django_cfg/modules/django_twilio/sms.py +1 -0
- django_cfg/modules/django_twilio/twilio_service.py +79 -83
- django_cfg/modules/django_twilio/unified.py +6 -5
- django_cfg/modules/django_twilio/utils.py +2 -3
- django_cfg/modules/django_twilio/whatsapp.py +3 -2
- django_cfg/modules/django_unfold/__init__.py +7 -6
- django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
- django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
- django_cfg/modules/django_unfold/callbacks/base.py +9 -8
- django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
- django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
- django_cfg/modules/django_unfold/callbacks/main.py +27 -27
- django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
- django_cfg/modules/django_unfold/callbacks/system.py +5 -5
- django_cfg/modules/django_unfold/callbacks/users.py +4 -4
- django_cfg/modules/django_unfold/dashboard.py +29 -29
- django_cfg/modules/django_unfold/models/__init__.py +23 -8
- django_cfg/modules/django_unfold/models/config.py +84 -81
- django_cfg/modules/django_unfold/models/dashboard.py +20 -19
- django_cfg/modules/django_unfold/models/dropdown.py +6 -4
- django_cfg/modules/django_unfold/models/navigation.py +6 -4
- django_cfg/modules/django_unfold/models/tabs.py +4 -3
- django_cfg/modules/django_unfold/models.py +2 -3
- django_cfg/modules/django_unfold/system_monitor.py +27 -25
- django_cfg/modules/django_unfold/tailwind.py +12 -14
- django_cfg/modules/django_unfold/utils.py +7 -6
- django_cfg/pyproject.toml +1 -1
- django_cfg/registry/__init__.py +3 -3
- django_cfg/registry/core.py +8 -8
- django_cfg/registry/modules.py +2 -2
- django_cfg/registry/services.py +2 -2
- django_cfg/registry/third_party.py +3 -3
- django_cfg/routing/__init__.py +3 -3
- django_cfg/routing/callbacks.py +27 -26
- django_cfg/routing/routers.py +2 -2
- django_cfg/static/js/api/accounts/client.mjs +69 -0
- django_cfg/static/js/api/accounts/index.mjs +13 -0
- django_cfg/static/js/api/base.mjs +166 -0
- django_cfg/static/js/api/index.mjs +100 -0
- django_cfg/static/js/api/ipc/client.mjs +74 -0
- django_cfg/static/js/api/ipc/index.mjs +13 -0
- django_cfg/static/js/api/leads/client.mjs +71 -0
- django_cfg/static/js/api/leads/index.mjs +13 -0
- django_cfg/static/js/api/newsletter/client.mjs +109 -0
- django_cfg/static/js/api/newsletter/index.mjs +13 -0
- django_cfg/static/js/api/payments/client.mjs +1264 -0
- django_cfg/static/js/api/payments/index.mjs +13 -0
- django_cfg/static/js/api/support/client.mjs +84 -0
- django_cfg/static/js/api/support/index.mjs +13 -0
- django_cfg/static/js/api/tasks/client.mjs +74 -0
- django_cfg/static/js/api/tasks/index.mjs +13 -0
- django_cfg/static/js/api/types.mjs +729 -0
- django_cfg/static/js/api-loader.mjs +169 -0
- django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
- django_cfg/templatetags/django_cfg.py +4 -4
- django_cfg/utils/path_resolution.py +49 -50
- django_cfg/utils/smart_defaults.py +27 -29
- django_cfg/utils/version_check.py +14 -14
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/METADATA +1 -1
- django_cfg-1.4.23.dist-info/RECORD +1137 -0
- django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
- django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
- django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
- django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
- django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
- django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
- django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
- django_cfg/modules/django_rpc_old/POETRY.md +0 -344
- django_cfg/modules/django_rpc_old/README.md +0 -397
- django_cfg/modules/django_rpc_old/TESTING.md +0 -358
- django_cfg/modules/django_rpc_old/__init__.py +0 -39
- django_cfg/modules/django_rpc_old/client.py +0 -531
- django_cfg/modules/django_rpc_old/config.py +0 -279
- django_cfg/modules/django_rpc_old/exceptions.py +0 -172
- django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
- django_cfg-1.4.21.dist-info/RECORD +0 -1111
- /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
- /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -7,20 +7,16 @@ Uses specialized chunkers for different content types.
|
|
7
7
|
|
8
8
|
import logging
|
9
9
|
from typing import List, Optional
|
10
|
+
|
10
11
|
from django.contrib.auth import get_user_model
|
11
12
|
|
12
13
|
from ...models.archive import ArchiveItem, ArchiveItemChunk
|
13
14
|
from ...utils.chunk_settings import get_chunking_params_for_type
|
14
15
|
from ..base import BaseService
|
15
|
-
from .exceptions import ChunkingError
|
16
16
|
|
17
17
|
# Import chunkers
|
18
|
-
from .chunking import
|
19
|
-
|
20
|
-
MarkdownChunker,
|
21
|
-
JsonChunker,
|
22
|
-
TextChunker
|
23
|
-
)
|
18
|
+
from .chunking import JsonChunker, MarkdownChunker, PythonChunker, TextChunker
|
19
|
+
from .exceptions import ChunkingError
|
24
20
|
|
25
21
|
User = get_user_model()
|
26
22
|
logger = logging.getLogger(__name__)
|
@@ -4,8 +4,8 @@ Context building for chunks.
|
|
4
4
|
Models and builders for chunk context metadata.
|
5
5
|
"""
|
6
6
|
|
7
|
-
from .models import ChunkContextMetadata, ChunkData
|
8
7
|
from .builders import ChunkContextBuilder
|
8
|
+
from .models import ChunkContextMetadata, ChunkData
|
9
9
|
|
10
10
|
__all__ = [
|
11
11
|
'ChunkContextMetadata',
|
@@ -4,16 +4,16 @@ Archive processing exceptions.
|
|
4
4
|
Custom exception hierarchy for archive processing operations.
|
5
5
|
"""
|
6
6
|
|
7
|
-
from typing import
|
7
|
+
from typing import Any, Dict, Optional
|
8
8
|
|
9
9
|
|
10
10
|
class ArchiveProcessingError(Exception):
|
11
11
|
"""Base exception for archive processing errors."""
|
12
|
-
|
12
|
+
|
13
13
|
def __init__(
|
14
|
-
self,
|
15
|
-
message: str,
|
16
|
-
code: str,
|
14
|
+
self,
|
15
|
+
message: str,
|
16
|
+
code: str,
|
17
17
|
details: Optional[Dict[str, Any]] = None
|
18
18
|
):
|
19
19
|
self.message = message
|
@@ -4,24 +4,25 @@ Archive extraction services.
|
|
4
4
|
Handles extraction of different archive formats and content processing.
|
5
5
|
"""
|
6
6
|
|
7
|
+
import hashlib
|
8
|
+
import mimetypes
|
7
9
|
import os
|
8
|
-
import
|
10
|
+
import shutil
|
9
11
|
import tarfile
|
10
12
|
import tempfile
|
11
|
-
import
|
12
|
-
import hashlib
|
13
|
-
import mimetypes
|
13
|
+
import zipfile
|
14
14
|
from pathlib import Path
|
15
|
-
from typing import
|
15
|
+
from typing import Any, Dict, List, Optional, Set
|
16
|
+
|
16
17
|
from pydantic import BaseModel
|
17
18
|
|
18
19
|
from ...models.archive import ArchiveType, ContentType
|
19
|
-
from .exceptions import ExtractionError
|
20
|
+
from .exceptions import ExtractionError
|
20
21
|
|
21
22
|
|
22
23
|
class ExtractedItemData(BaseModel):
|
23
24
|
"""Data structure for extracted archive item."""
|
24
|
-
|
25
|
+
|
25
26
|
relative_path: str
|
26
27
|
item_name: str
|
27
28
|
file_size: int
|
@@ -35,10 +36,10 @@ class ExtractedItemData(BaseModel):
|
|
35
36
|
|
36
37
|
class ArchiveExtractionService:
|
37
38
|
"""Service for extracting archives and processing content."""
|
38
|
-
|
39
|
+
|
39
40
|
# File size limits
|
40
41
|
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB per file
|
41
|
-
|
42
|
+
|
42
43
|
# Text file extensions
|
43
44
|
TEXT_EXTENSIONS: Set[str] = {
|
44
45
|
'.py', '.js', '.ts', '.jsx', '.tsx', '.java', '.go', '.rs',
|
@@ -51,57 +52,57 @@ class ArchiveExtractionService:
|
|
51
52
|
'.dockerfile', '.makefile', '.gitignore', '.env',
|
52
53
|
'.tf', '.hcl'
|
53
54
|
}
|
54
|
-
|
55
|
+
|
55
56
|
def extract_archive(
|
56
|
-
self,
|
57
|
-
archive_path: str,
|
57
|
+
self,
|
58
|
+
archive_path: str,
|
58
59
|
archive_type: str
|
59
60
|
) -> List[ExtractedItemData]:
|
60
61
|
"""Extract archive and return processed item data."""
|
61
|
-
|
62
|
+
|
62
63
|
extract_dir = tempfile.mkdtemp(prefix='extracted_')
|
63
|
-
|
64
|
+
|
64
65
|
try:
|
65
66
|
# Extract based on type
|
66
67
|
file_list = self._extract_by_type(archive_path, archive_type, extract_dir)
|
67
|
-
|
68
|
+
|
68
69
|
# Process extracted files
|
69
70
|
extracted_items = []
|
70
|
-
|
71
|
+
|
71
72
|
for relative_path in file_list:
|
72
73
|
full_path = os.path.join(extract_dir, relative_path)
|
73
|
-
|
74
|
+
|
74
75
|
# Skip directories
|
75
76
|
if os.path.isdir(full_path):
|
76
77
|
continue
|
77
|
-
|
78
|
+
|
78
79
|
# Skip unwanted files
|
79
80
|
if self._should_skip_file(relative_path):
|
80
81
|
continue
|
81
|
-
|
82
|
+
|
82
83
|
try:
|
83
84
|
item_data = self._process_extracted_file(full_path, relative_path)
|
84
85
|
if item_data:
|
85
86
|
extracted_items.append(item_data)
|
86
|
-
except Exception
|
87
|
+
except Exception:
|
87
88
|
# Log error but continue with other files
|
88
89
|
continue
|
89
|
-
|
90
|
+
|
90
91
|
return extracted_items
|
91
|
-
|
92
|
+
|
92
93
|
finally:
|
93
94
|
# Always cleanup extraction directory
|
94
95
|
if os.path.exists(extract_dir):
|
95
96
|
shutil.rmtree(extract_dir)
|
96
|
-
|
97
|
+
|
97
98
|
def _extract_by_type(
|
98
|
-
self,
|
99
|
-
archive_path: str,
|
100
|
-
archive_type: str,
|
99
|
+
self,
|
100
|
+
archive_path: str,
|
101
|
+
archive_type: str,
|
101
102
|
extract_dir: str
|
102
103
|
) -> List[str]:
|
103
104
|
"""Extract archive based on its type."""
|
104
|
-
|
105
|
+
|
105
106
|
try:
|
106
107
|
if archive_type == ArchiveType.ZIP:
|
107
108
|
return self._extract_zip(archive_path, extract_dir)
|
@@ -116,53 +117,53 @@ class ArchiveExtractionService:
|
|
116
117
|
except Exception as e:
|
117
118
|
if isinstance(e, ExtractionError):
|
118
119
|
raise
|
119
|
-
|
120
|
+
|
120
121
|
raise ExtractionError(
|
121
122
|
message=f"Failed to extract archive: {str(e)}",
|
122
123
|
code="EXTRACTION_FAILED",
|
123
124
|
details={"archive_path": archive_path, "error": str(e)}
|
124
125
|
) from e
|
125
|
-
|
126
|
+
|
126
127
|
def _extract_zip(self, archive_path: str, extract_dir: str) -> List[str]:
|
127
128
|
"""Extract ZIP archive."""
|
128
129
|
with zipfile.ZipFile(archive_path, 'r') as zip_file:
|
129
130
|
# Check for zip bomb
|
130
131
|
self._check_zip_bomb(zip_file)
|
131
|
-
|
132
|
+
|
132
133
|
zip_file.extractall(extract_dir)
|
133
134
|
return zip_file.namelist()
|
134
|
-
|
135
|
+
|
135
136
|
def _extract_tar(
|
136
|
-
self,
|
137
|
-
archive_path: str,
|
138
|
-
archive_type: str,
|
137
|
+
self,
|
138
|
+
archive_path: str,
|
139
|
+
archive_type: str,
|
139
140
|
extract_dir: str
|
140
141
|
) -> List[str]:
|
141
142
|
"""Extract TAR archive (including compressed variants)."""
|
142
|
-
|
143
|
+
|
143
144
|
mode_map = {
|
144
145
|
ArchiveType.TAR: 'r',
|
145
146
|
ArchiveType.TAR_GZ: 'r:gz',
|
146
147
|
ArchiveType.TAR_BZ2: 'r:bz2'
|
147
148
|
}
|
148
|
-
|
149
|
+
|
149
150
|
with tarfile.open(archive_path, mode_map[archive_type]) as tar_file:
|
150
151
|
# Security check for path traversal
|
151
152
|
self._check_tar_security(tar_file)
|
152
|
-
|
153
|
+
|
153
154
|
tar_file.extractall(extract_dir)
|
154
155
|
return tar_file.getnames()
|
155
|
-
|
156
|
+
|
156
157
|
def _check_zip_bomb(self, zip_file: zipfile.ZipFile) -> None:
|
157
158
|
"""Check for zip bomb attacks."""
|
158
|
-
|
159
|
+
|
159
160
|
total_uncompressed = 0
|
160
161
|
total_compressed = 0
|
161
|
-
|
162
|
+
|
162
163
|
for info in zip_file.infolist():
|
163
164
|
total_uncompressed += info.file_size
|
164
165
|
total_compressed += info.compress_size
|
165
|
-
|
166
|
+
|
166
167
|
# Check compression ratio
|
167
168
|
if total_compressed > 0:
|
168
169
|
ratio = total_uncompressed / total_compressed
|
@@ -175,7 +176,7 @@ class ArchiveExtractionService:
|
|
175
176
|
"uncompressed_size": total_uncompressed
|
176
177
|
}
|
177
178
|
)
|
178
|
-
|
179
|
+
|
179
180
|
# Check total uncompressed size
|
180
181
|
if total_uncompressed > 1024 * 1024 * 1024: # 1GB limit
|
181
182
|
raise ExtractionError(
|
@@ -183,10 +184,10 @@ class ArchiveExtractionService:
|
|
183
184
|
code="ARCHIVE_TOO_LARGE_UNCOMPRESSED",
|
184
185
|
details={"uncompressed_size": total_uncompressed}
|
185
186
|
)
|
186
|
-
|
187
|
+
|
187
188
|
def _check_tar_security(self, tar_file: tarfile.TarFile) -> None:
|
188
189
|
"""Check TAR file for security issues."""
|
189
|
-
|
190
|
+
|
190
191
|
for member in tar_file.getmembers():
|
191
192
|
# Check for path traversal
|
192
193
|
if os.path.isabs(member.name) or ".." in member.name:
|
@@ -195,7 +196,7 @@ class ArchiveExtractionService:
|
|
195
196
|
code="PATH_TRAVERSAL_DETECTED",
|
196
197
|
details={"member_name": member.name}
|
197
198
|
)
|
198
|
-
|
199
|
+
|
199
200
|
# Check for suspicious file sizes
|
200
201
|
if member.size > self.MAX_FILE_SIZE * 10: # 100MB limit per file
|
201
202
|
raise ExtractionError(
|
@@ -206,89 +207,89 @@ class ArchiveExtractionService:
|
|
206
207
|
"file_size": member.size
|
207
208
|
}
|
208
209
|
)
|
209
|
-
|
210
|
+
|
210
211
|
def _should_skip_file(self, relative_path: str) -> bool:
|
211
212
|
"""Check if file should be skipped during processing."""
|
212
|
-
|
213
|
+
|
213
214
|
# Normalize path for consistent checking
|
214
215
|
relative_path_lower = relative_path.lower()
|
215
216
|
path_parts = relative_path_lower.split('/')
|
216
|
-
|
217
|
+
|
217
218
|
# Check for hidden files (starting with dot)
|
218
219
|
for part in path_parts:
|
219
220
|
if part.startswith('.') and part not in ['.', '..']:
|
220
221
|
return True
|
221
|
-
|
222
|
+
|
222
223
|
# Check for system/build directories
|
223
224
|
skip_directories = {
|
224
225
|
'__pycache__', 'node_modules', 'dist', 'build', 'target',
|
225
226
|
'.git', '.svn', '.hg', '.vscode', '.idea', '.eclipse'
|
226
227
|
}
|
227
|
-
|
228
|
+
|
228
229
|
for part in path_parts:
|
229
230
|
if part in skip_directories:
|
230
231
|
return True
|
231
|
-
|
232
|
+
|
232
233
|
# Check file extensions
|
233
234
|
skip_extensions = {
|
234
235
|
'.pyc', '.pyo', '.tmp', '.temp', '.swp', '.bak',
|
235
236
|
'.exe', '.dll', '.so', '.dylib', '.jar', '.war', '.ear', '.iso', '.dmg'
|
236
237
|
}
|
237
|
-
|
238
|
+
|
238
239
|
for ext in skip_extensions:
|
239
240
|
if relative_path_lower.endswith(ext):
|
240
241
|
return True
|
241
|
-
|
242
|
+
|
242
243
|
# Check specific filenames
|
243
244
|
filename = path_parts[-1] if path_parts else ''
|
244
245
|
skip_filenames = {'.ds_store', 'thumbs.db'}
|
245
|
-
|
246
|
+
|
246
247
|
if filename in skip_filenames:
|
247
248
|
return True
|
248
|
-
|
249
|
+
|
249
250
|
# Skip very deep paths (potential zip bomb)
|
250
251
|
if relative_path.count('/') > 10:
|
251
252
|
return True
|
252
|
-
|
253
|
+
|
253
254
|
return False
|
254
|
-
|
255
|
+
|
255
256
|
def _process_extracted_file(
|
256
|
-
self,
|
257
|
-
full_path: str,
|
257
|
+
self,
|
258
|
+
full_path: str,
|
258
259
|
relative_path: str
|
259
260
|
) -> Optional[ExtractedItemData]:
|
260
261
|
"""Process individual extracted file."""
|
261
|
-
|
262
|
+
|
262
263
|
try:
|
263
264
|
stat = os.stat(full_path)
|
264
265
|
file_size = stat.st_size
|
265
|
-
|
266
|
+
|
266
267
|
# Skip very large files
|
267
268
|
if file_size > self.MAX_FILE_SIZE:
|
268
269
|
return None
|
269
|
-
|
270
|
+
|
270
271
|
item_name = os.path.basename(relative_path)
|
271
|
-
|
272
|
+
|
272
273
|
# Detect content type and processability
|
273
274
|
content_type = self._detect_content_type(item_name, full_path)
|
274
275
|
is_text_file = self._is_text_file(item_name, full_path)
|
275
276
|
is_processable = is_text_file and content_type in [
|
276
|
-
ContentType.DOCUMENT,
|
277
|
-
ContentType.CODE,
|
277
|
+
ContentType.DOCUMENT,
|
278
|
+
ContentType.CODE,
|
278
279
|
ContentType.DATA
|
279
280
|
]
|
280
|
-
|
281
|
+
|
281
282
|
# Extract content for processable files
|
282
283
|
content = None
|
283
284
|
if is_processable:
|
284
285
|
content = self._extract_text_content(full_path)
|
285
|
-
|
286
|
+
|
286
287
|
# Generate content hash
|
287
288
|
content_hash = self._generate_content_hash(full_path, content)
|
288
|
-
|
289
|
+
|
289
290
|
# Detect language
|
290
291
|
language = self._detect_language(item_name, content_type)
|
291
|
-
|
292
|
+
|
292
293
|
# Build metadata
|
293
294
|
metadata = {
|
294
295
|
'mime_type': mimetypes.guess_type(item_name)[0] or 'application/octet-stream',
|
@@ -296,7 +297,7 @@ class ArchiveExtractionService:
|
|
296
297
|
'extraction_method': 'direct_read' if is_text_file else 'binary_skip',
|
297
298
|
'file_extension': Path(item_name).suffix.lower(),
|
298
299
|
}
|
299
|
-
|
300
|
+
|
300
301
|
return ExtractedItemData(
|
301
302
|
relative_path=relative_path,
|
302
303
|
item_name=item_name,
|
@@ -308,44 +309,44 @@ class ArchiveExtractionService:
|
|
308
309
|
language=language,
|
309
310
|
metadata=metadata
|
310
311
|
)
|
311
|
-
|
312
|
-
except Exception
|
312
|
+
|
313
|
+
except Exception:
|
313
314
|
# Return None for problematic files
|
314
315
|
return None
|
315
|
-
|
316
|
+
|
316
317
|
def _detect_content_type(self, item_name: str, full_path: str) -> str:
|
317
318
|
"""Detect content type from file extension and content."""
|
318
|
-
|
319
|
+
|
319
320
|
file_path = Path(item_name)
|
320
321
|
extension = file_path.suffix.lower()
|
321
|
-
|
322
|
+
|
322
323
|
# Code files
|
323
324
|
code_extensions = {
|
324
325
|
'.py', '.js', '.ts', '.jsx', '.tsx', '.java', '.go', '.rs',
|
325
326
|
'.cpp', '.c', '.h', '.hpp', '.php', '.rb', '.cs', '.swift',
|
326
327
|
'.kt', '.scala', '.clj', '.hs', '.ml', '.fs', '.elm'
|
327
328
|
}
|
328
|
-
|
329
|
+
|
329
330
|
# Document files
|
330
331
|
document_extensions = {
|
331
332
|
'.md', '.txt', '.rst', '.adoc', '.pdf', '.docx', '.doc'
|
332
333
|
}
|
333
|
-
|
334
|
+
|
334
335
|
# Data files
|
335
336
|
data_extensions = {
|
336
337
|
'.json', '.csv', '.xml', '.yml', '.yaml', '.toml', '.ini'
|
337
338
|
}
|
338
|
-
|
339
|
+
|
339
340
|
# Image files
|
340
341
|
image_extensions = {
|
341
342
|
'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'
|
342
343
|
}
|
343
|
-
|
344
|
+
|
344
345
|
# Archive files
|
345
346
|
archive_extensions = {
|
346
347
|
'.zip', '.tar', '.gz', '.bz2', '.7z', '.rar'
|
347
348
|
}
|
348
|
-
|
349
|
+
|
349
350
|
if extension in code_extensions:
|
350
351
|
return ContentType.CODE
|
351
352
|
elif extension in document_extensions:
|
@@ -358,78 +359,78 @@ class ArchiveExtractionService:
|
|
358
359
|
return ContentType.ARCHIVE
|
359
360
|
else:
|
360
361
|
return ContentType.UNKNOWN
|
361
|
-
|
362
|
+
|
362
363
|
def _is_text_file(self, item_name: str, full_path: str) -> bool:
|
363
364
|
"""Check if file is a text file."""
|
364
|
-
|
365
|
+
|
365
366
|
# Check by extension first
|
366
367
|
file_path = Path(item_name)
|
367
368
|
extension = file_path.suffix.lower()
|
368
|
-
|
369
|
+
|
369
370
|
if extension in self.TEXT_EXTENSIONS:
|
370
371
|
return True
|
371
|
-
|
372
|
+
|
372
373
|
# Special filenames
|
373
374
|
special_names = {
|
374
375
|
'dockerfile', 'makefile', 'readme', 'license', 'changelog',
|
375
376
|
'.gitignore', '.dockerignore', '.env', '.settings.example'
|
376
377
|
}
|
377
|
-
|
378
|
+
|
378
379
|
if file_path.name.lower() in special_names:
|
379
380
|
return True
|
380
|
-
|
381
|
+
|
381
382
|
# Try to detect by content (sample first 1KB)
|
382
383
|
try:
|
383
384
|
with open(full_path, 'rb') as f:
|
384
385
|
sample = f.read(1024)
|
385
|
-
|
386
|
+
|
386
387
|
# Check for null bytes (binary indicator)
|
387
388
|
if b'\x00' in sample:
|
388
389
|
return False
|
389
|
-
|
390
|
+
|
390
391
|
# Try to decode as UTF-8
|
391
392
|
try:
|
392
393
|
sample.decode('utf-8')
|
393
394
|
return True
|
394
395
|
except UnicodeDecodeError:
|
395
396
|
return False
|
396
|
-
|
397
|
+
|
397
398
|
except Exception:
|
398
399
|
return False
|
399
|
-
|
400
|
+
|
400
401
|
def _extract_text_content(self, full_path: str) -> Optional[str]:
|
401
402
|
"""Extract text content from file."""
|
402
|
-
|
403
|
+
|
403
404
|
try:
|
404
405
|
# Try different encodings
|
405
406
|
encodings = ['utf-8', 'utf-16', 'latin1', 'cp1252']
|
406
|
-
|
407
|
+
|
407
408
|
for encoding in encodings:
|
408
409
|
try:
|
409
|
-
with open(full_path,
|
410
|
+
with open(full_path, encoding=encoding) as f:
|
410
411
|
content = f.read()
|
411
|
-
|
412
|
+
|
412
413
|
# Validate content is reasonable
|
413
414
|
if len(content) > 0 and len(content) < 1024 * 1024: # Max 1MB text
|
414
415
|
return content
|
415
|
-
|
416
|
+
|
416
417
|
except UnicodeDecodeError:
|
417
418
|
continue
|
418
419
|
except Exception:
|
419
420
|
break
|
420
|
-
|
421
|
+
|
421
422
|
return None
|
422
|
-
|
423
|
+
|
423
424
|
except Exception:
|
424
425
|
return None
|
425
|
-
|
426
|
+
|
426
427
|
def _generate_content_hash(
|
427
|
-
self,
|
428
|
-
full_path: str,
|
428
|
+
self,
|
429
|
+
full_path: str,
|
429
430
|
content: Optional[str]
|
430
431
|
) -> str:
|
431
432
|
"""Generate SHA-256 hash of file content."""
|
432
|
-
|
433
|
+
|
433
434
|
if content:
|
434
435
|
return hashlib.sha256(content.encode()).hexdigest()
|
435
436
|
else:
|
@@ -443,13 +444,13 @@ class ArchiveExtractionService:
|
|
443
444
|
except Exception:
|
444
445
|
# Fallback to path-based hash
|
445
446
|
return hashlib.sha256(full_path.encode()).hexdigest()
|
446
|
-
|
447
|
+
|
447
448
|
def _detect_language(self, item_name: str, content_type: str) -> Optional[str]:
|
448
449
|
"""Detect programming language from file extension."""
|
449
|
-
|
450
|
+
|
450
451
|
if content_type != ContentType.CODE:
|
451
452
|
return None
|
452
|
-
|
453
|
+
|
453
454
|
language_map = {
|
454
455
|
'.py': 'python',
|
455
456
|
'.js': 'javascript',
|
@@ -473,34 +474,34 @@ class ArchiveExtractionService:
|
|
473
474
|
'.fs': 'fsharp',
|
474
475
|
'.elm': 'elm',
|
475
476
|
}
|
476
|
-
|
477
|
+
|
477
478
|
file_path = Path(item_name)
|
478
479
|
extension = file_path.suffix.lower()
|
479
|
-
|
480
|
+
|
480
481
|
# Special cases
|
481
482
|
if file_path.name.lower() in ['dockerfile']:
|
482
483
|
return 'dockerfile'
|
483
484
|
elif file_path.name.lower() in ['makefile']:
|
484
485
|
return 'makefile'
|
485
|
-
|
486
|
+
|
486
487
|
return language_map.get(extension)
|
487
488
|
|
488
489
|
|
489
490
|
class ContentExtractionService:
|
490
491
|
"""Service for extracting content from specific file types."""
|
491
|
-
|
492
|
+
|
492
493
|
def extract_pdf_content(self, file_path: str) -> Optional[str]:
|
493
494
|
"""Extract text from PDF file."""
|
494
495
|
# TODO: Implement PDF text extraction
|
495
496
|
# Could use PyPDF2, pdfplumber, or similar
|
496
497
|
return None
|
497
|
-
|
498
|
+
|
498
499
|
def extract_docx_content(self, file_path: str) -> Optional[str]:
|
499
500
|
"""Extract text from DOCX file."""
|
500
501
|
# TODO: Implement DOCX text extraction
|
501
502
|
# Could use python-docx
|
502
503
|
return None
|
503
|
-
|
504
|
+
|
504
505
|
def extract_image_text(self, file_path: str) -> Optional[str]:
|
505
506
|
"""Extract text from image using OCR."""
|
506
507
|
# TODO: Implement OCR text extraction
|