django-cfg 1.2.29__py3-none-any.whl → 1.3.1__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 +1 -1
- django_cfg/apps/api/health/views.py +4 -2
- django_cfg/apps/knowbase/config/settings.py +16 -15
- django_cfg/apps/payments/README.md +326 -0
- django_cfg/apps/payments/admin/__init__.py +20 -9
- django_cfg/apps/payments/admin/api_keys_admin.py +521 -237
- django_cfg/apps/payments/admin/balance_admin.py +592 -297
- django_cfg/apps/payments/admin/currencies_admin.py +600 -108
- django_cfg/apps/payments/admin/filters.py +306 -199
- django_cfg/apps/payments/admin/payments_admin.py +470 -64
- django_cfg/apps/payments/admin/subscriptions_admin.py +578 -128
- django_cfg/apps/payments/admin_interface/__init__.py +18 -0
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +162 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/dev_tool_card.html +38 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/loading_spinner.html +16 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/notification.html +27 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/provider_card.html +86 -0
- django_cfg/apps/payments/admin_interface/templates/payments/components/status_card.html +39 -0
- django_cfg/apps/payments/admin_interface/templates/payments/currency_converter.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +300 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +303 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +382 -0
- django_cfg/apps/payments/admin_interface/templates/payments/payment_status.html +500 -0
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +594 -0
- django_cfg/apps/payments/admin_interface/views/__init__.py +23 -0
- django_cfg/apps/payments/admin_interface/views/payment_views.py +259 -0
- django_cfg/apps/payments/admin_interface/views/webhook_dashboard.py +37 -0
- django_cfg/apps/payments/apps.py +34 -9
- django_cfg/apps/payments/config/__init__.py +28 -51
- django_cfg/apps/payments/config/constance/__init__.py +22 -0
- django_cfg/apps/payments/config/constance/config_service.py +123 -0
- django_cfg/apps/payments/config/constance/fields.py +69 -0
- django_cfg/apps/payments/config/constance/settings.py +160 -0
- django_cfg/apps/payments/config/django_cfg_integration.py +202 -0
- django_cfg/apps/payments/config/helpers.py +130 -0
- django_cfg/apps/payments/management/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/__init__.py +1 -3
- django_cfg/apps/payments/management/commands/manage_currencies.py +381 -0
- django_cfg/apps/payments/management/commands/manage_providers.py +408 -0
- django_cfg/apps/payments/middleware/__init__.py +3 -1
- django_cfg/apps/payments/middleware/api_access.py +329 -222
- django_cfg/apps/payments/middleware/rate_limiting.py +343 -163
- django_cfg/apps/payments/middleware/usage_tracking.py +250 -238
- django_cfg/apps/payments/migrations/0001_initial.py +708 -536
- django_cfg/apps/payments/models/__init__.py +16 -20
- django_cfg/apps/payments/models/api_keys.py +121 -43
- django_cfg/apps/payments/models/balance.py +150 -115
- django_cfg/apps/payments/models/base.py +68 -15
- django_cfg/apps/payments/models/currencies.py +207 -67
- django_cfg/apps/payments/models/managers/__init__.py +44 -0
- django_cfg/apps/payments/models/managers/api_key_managers.py +329 -0
- django_cfg/apps/payments/models/managers/balance_managers.py +599 -0
- django_cfg/apps/payments/models/managers/currency_managers.py +385 -0
- django_cfg/apps/payments/models/managers/payment_managers.py +511 -0
- django_cfg/apps/payments/models/managers/subscription_managers.py +641 -0
- django_cfg/apps/payments/models/payments.py +235 -284
- django_cfg/apps/payments/models/subscriptions.py +257 -177
- django_cfg/apps/payments/models/tariffs.py +147 -40
- django_cfg/apps/payments/services/__init__.py +209 -56
- django_cfg/apps/payments/services/cache/__init__.py +6 -6
- django_cfg/apps/payments/services/cache/{simple_cache.py → cache_service.py} +112 -12
- django_cfg/apps/payments/services/core/__init__.py +10 -6
- django_cfg/apps/payments/services/core/balance_service.py +435 -360
- django_cfg/apps/payments/services/core/base.py +166 -0
- django_cfg/apps/payments/services/core/currency_service.py +478 -0
- django_cfg/apps/payments/services/core/payment_service.py +344 -468
- django_cfg/apps/payments/services/core/subscription_service.py +425 -484
- django_cfg/apps/payments/services/core/webhook_service.py +410 -0
- django_cfg/apps/payments/services/integrations/__init__.py +29 -0
- django_cfg/apps/payments/services/integrations/ngrok_service.py +47 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +107 -0
- django_cfg/apps/payments/services/providers/__init__.py +9 -14
- django_cfg/apps/payments/services/providers/base.py +232 -71
- django_cfg/apps/payments/services/providers/nowpayments.py +404 -219
- django_cfg/apps/payments/services/providers/registry.py +429 -80
- django_cfg/apps/payments/services/types/__init__.py +78 -0
- django_cfg/apps/payments/services/types/data.py +177 -0
- django_cfg/apps/payments/services/types/requests.py +150 -0
- django_cfg/apps/payments/services/types/responses.py +156 -0
- django_cfg/apps/payments/services/types/webhooks.py +232 -0
- django_cfg/apps/payments/signals/__init__.py +33 -8
- django_cfg/apps/payments/signals/api_key_signals.py +211 -130
- django_cfg/apps/payments/signals/balance_signals.py +174 -0
- django_cfg/apps/payments/signals/payment_signals.py +129 -98
- django_cfg/apps/payments/signals/subscription_signals.py +195 -143
- django_cfg/apps/payments/static/payments/css/components.css +380 -0
- django_cfg/apps/payments/static/payments/css/dashboard.css +188 -0
- django_cfg/apps/payments/static/payments/js/components.js +545 -0
- django_cfg/apps/payments/static/payments/js/utils.js +412 -0
- django_cfg/apps/payments/templatetags/__init__.py +1 -1
- django_cfg/apps/payments/templatetags/payment_tags.py +466 -0
- django_cfg/apps/payments/urls.py +46 -47
- django_cfg/apps/payments/urls_admin.py +49 -0
- django_cfg/apps/payments/views/api/__init__.py +101 -0
- django_cfg/apps/payments/views/api/api_keys.py +387 -0
- django_cfg/apps/payments/views/api/balances.py +381 -0
- django_cfg/apps/payments/views/api/base.py +298 -0
- django_cfg/apps/payments/views/api/currencies.py +402 -0
- django_cfg/apps/payments/views/api/payments.py +415 -0
- django_cfg/apps/payments/views/api/subscriptions.py +475 -0
- django_cfg/apps/payments/views/api/webhooks.py +476 -0
- django_cfg/apps/payments/views/serializers/__init__.py +99 -0
- django_cfg/apps/payments/views/serializers/api_keys.py +424 -0
- django_cfg/apps/payments/views/serializers/balances.py +300 -0
- django_cfg/apps/payments/views/serializers/currencies.py +335 -0
- django_cfg/apps/payments/views/serializers/payments.py +387 -0
- django_cfg/apps/payments/views/serializers/subscriptions.py +429 -0
- django_cfg/apps/payments/views/serializers/webhooks.py +137 -0
- django_cfg/apps/tasks/urls.py +0 -2
- django_cfg/apps/tasks/urls_admin.py +14 -0
- django_cfg/apps/urls.py +4 -4
- django_cfg/config.py +1 -1
- django_cfg/core/config.py +75 -4
- django_cfg/core/generation.py +25 -4
- django_cfg/core/integration/README.md +363 -0
- django_cfg/core/integration/__init__.py +47 -0
- django_cfg/core/integration/commands_collector.py +239 -0
- django_cfg/core/integration/display/__init__.py +15 -0
- django_cfg/core/integration/display/base.py +157 -0
- django_cfg/core/integration/display/ngrok.py +164 -0
- django_cfg/core/integration/display/startup.py +815 -0
- django_cfg/core/integration/url_integration.py +123 -0
- django_cfg/core/integration/version_checker.py +160 -0
- django_cfg/management/commands/auto_generate.py +4 -0
- django_cfg/management/commands/check_settings.py +6 -0
- django_cfg/management/commands/clear_constance.py +5 -2
- django_cfg/management/commands/create_token.py +6 -0
- django_cfg/management/commands/list_urls.py +6 -0
- django_cfg/management/commands/migrate_all.py +6 -0
- django_cfg/management/commands/migrator.py +3 -0
- django_cfg/management/commands/rundramatiq.py +6 -0
- django_cfg/management/commands/runserver_ngrok.py +51 -29
- django_cfg/management/commands/script.py +6 -0
- django_cfg/management/commands/show_config.py +12 -2
- django_cfg/management/commands/show_urls.py +4 -0
- django_cfg/management/commands/superuser.py +6 -0
- django_cfg/management/commands/task_clear.py +4 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -0
- django_cfg/management/commands/test_telegram.py +6 -0
- django_cfg/management/commands/test_twilio.py +6 -0
- django_cfg/management/commands/tree.py +6 -0
- django_cfg/management/commands/validate_config.py +155 -149
- django_cfg/models/constance.py +31 -11
- django_cfg/models/payments.py +175 -498
- django_cfg/modules/django_currency/__init__.py +16 -11
- django_cfg/modules/django_currency/clients/__init__.py +4 -4
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
- django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
- django_cfg/modules/django_currency/core/__init__.py +1 -7
- django_cfg/modules/django_currency/core/converter.py +18 -23
- django_cfg/modules/django_currency/core/models.py +122 -11
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +190 -309
- django_cfg/modules/django_logger.py +160 -146
- django_cfg/modules/django_unfold/dashboard.py +65 -12
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/admin/components/action_grid.html +9 -9
- django_cfg/templates/admin/components/metric_card.html +5 -5
- django_cfg/templates/admin/components/status_badge.html +2 -2
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
- django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
- django_cfg/templates/admin/snippets/components/system_health.html +1 -1
- django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
- django_cfg/utils/smart_defaults.py +222 -571
- django_cfg/utils/toolkit.py +51 -11
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/METADATA +5 -4
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/RECORD +172 -182
- django_cfg/apps/payments/__init__.py +0 -8
- django_cfg/apps/payments/admin/tariffs_admin.py +0 -199
- django_cfg/apps/payments/config/module.py +0 -70
- django_cfg/apps/payments/config/providers.py +0 -105
- django_cfg/apps/payments/config/settings.py +0 -96
- django_cfg/apps/payments/config/utils.py +0 -52
- django_cfg/apps/payments/decorators.py +0 -291
- django_cfg/apps/payments/management/commands/README.md +0 -178
- django_cfg/apps/payments/management/commands/currency_stats.py +0 -323
- django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
- django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
- django_cfg/apps/payments/managers/__init__.py +0 -22
- django_cfg/apps/payments/managers/api_key_manager.py +0 -35
- django_cfg/apps/payments/managers/balance_manager.py +0 -361
- django_cfg/apps/payments/managers/currency_manager.py +0 -83
- django_cfg/apps/payments/managers/payment_manager.py +0 -44
- django_cfg/apps/payments/managers/subscription_manager.py +0 -37
- django_cfg/apps/payments/managers/tariff_manager.py +0 -29
- django_cfg/apps/payments/models/events.py +0 -73
- django_cfg/apps/payments/serializers/__init__.py +0 -56
- django_cfg/apps/payments/serializers/api_keys.py +0 -51
- django_cfg/apps/payments/serializers/balance.py +0 -59
- django_cfg/apps/payments/serializers/currencies.py +0 -55
- django_cfg/apps/payments/serializers/payments.py +0 -62
- django_cfg/apps/payments/serializers/subscriptions.py +0 -71
- django_cfg/apps/payments/serializers/tariffs.py +0 -56
- django_cfg/apps/payments/services/billing/__init__.py +0 -8
- django_cfg/apps/payments/services/cache/base.py +0 -30
- django_cfg/apps/payments/services/core/fallback_service.py +0 -432
- django_cfg/apps/payments/services/internal_types.py +0 -297
- django_cfg/apps/payments/services/middleware/__init__.py +0 -8
- django_cfg/apps/payments/services/monitoring/__init__.py +0 -22
- django_cfg/apps/payments/services/monitoring/api_schemas.py +0 -222
- django_cfg/apps/payments/services/monitoring/provider_health.py +0 -372
- django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
- django_cfg/apps/payments/services/providers/cryptomus.py +0 -311
- django_cfg/apps/payments/services/security/__init__.py +0 -34
- django_cfg/apps/payments/services/security/error_handler.py +0 -637
- django_cfg/apps/payments/services/security/payment_notifications.py +0 -342
- django_cfg/apps/payments/services/security/webhook_validator.py +0 -475
- django_cfg/apps/payments/services/validators/__init__.py +0 -8
- django_cfg/apps/payments/static/payments/css/payments.css +0 -340
- django_cfg/apps/payments/static/payments/js/notifications.js +0 -202
- django_cfg/apps/payments/static/payments/js/payment-utils.js +0 -318
- django_cfg/apps/payments/static/payments/js/theme.js +0 -86
- django_cfg/apps/payments/tasks/__init__.py +0 -12
- django_cfg/apps/payments/tasks/webhook_processing.py +0 -177
- django_cfg/apps/payments/templates/payments/base.html +0 -182
- django_cfg/apps/payments/templates/payments/components/payment_card.html +0 -201
- django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +0 -109
- django_cfg/apps/payments/templates/payments/components/progress_bar.html +0 -36
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +0 -40
- django_cfg/apps/payments/templates/payments/components/status_badge.html +0 -27
- django_cfg/apps/payments/templates/payments/components/status_overview.html +0 -144
- django_cfg/apps/payments/templates/payments/dashboard.html +0 -346
- django_cfg/apps/payments/templatetags/payments_tags.py +0 -315
- django_cfg/apps/payments/urls_templates.py +0 -52
- django_cfg/apps/payments/utils/__init__.py +0 -45
- django_cfg/apps/payments/utils/billing_utils.py +0 -342
- django_cfg/apps/payments/utils/config_utils.py +0 -245
- django_cfg/apps/payments/utils/middleware_utils.py +0 -228
- django_cfg/apps/payments/utils/validation_utils.py +0 -94
- django_cfg/apps/payments/views/__init__.py +0 -62
- django_cfg/apps/payments/views/api_key_views.py +0 -164
- django_cfg/apps/payments/views/balance_views.py +0 -75
- django_cfg/apps/payments/views/currency_views.py +0 -111
- django_cfg/apps/payments/views/payment_views.py +0 -149
- django_cfg/apps/payments/views/subscription_views.py +0 -135
- django_cfg/apps/payments/views/tariff_views.py +0 -131
- django_cfg/apps/payments/views/templates/__init__.py +0 -25
- django_cfg/apps/payments/views/templates/ajax.py +0 -312
- django_cfg/apps/payments/views/templates/base.py +0 -204
- django_cfg/apps/payments/views/templates/dashboard.py +0 -60
- django_cfg/apps/payments/views/templates/payment_detail.py +0 -102
- django_cfg/apps/payments/views/templates/payment_management.py +0 -164
- django_cfg/apps/payments/views/templates/qr_code.py +0 -174
- django_cfg/apps/payments/views/templates/stats.py +0 -240
- django_cfg/apps/payments/views/templates/utils.py +0 -181
- django_cfg/apps/payments/views/webhook_views.py +0 -266
- django_cfg/apps/payments/viewsets.py +0 -65
- django_cfg/core/integration.py +0 -160
- django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
- django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
- django_cfg/template_archive/.gitignore +0 -1
- django_cfg/template_archive/__init__.py +0 -0
- django_cfg/urls.py +0 -33
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.29.dist-info → django_cfg-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,195 +1,209 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Simple auto-configuring Django Logger for django_cfg.
|
3
3
|
|
4
|
-
|
5
|
-
without requiring manual parameter passing.
|
4
|
+
KISS principle: simple, unified logging configuration.
|
6
5
|
"""
|
7
6
|
|
8
7
|
import logging
|
9
|
-
from typing import Optional, Dict, Any, Union
|
10
8
|
from pathlib import Path
|
9
|
+
from typing import Dict, Optional
|
11
10
|
|
12
11
|
from . import BaseCfgModule
|
12
|
+
from ..utils.smart_defaults import get_log_filename
|
13
13
|
|
14
14
|
|
15
15
|
class DjangoLogger(BaseCfgModule):
|
16
|
-
"""
|
17
|
-
Auto-configuring logger that gets settings from DjangoConfig.
|
18
|
-
|
19
|
-
Usage:
|
20
|
-
from django_cfg.modules import DjangoLogger
|
21
|
-
|
22
|
-
logger = DjangoLogger.get_logger("myapp")
|
23
|
-
logger.info("This works automatically!")
|
24
|
-
"""
|
16
|
+
"""Simple auto-configuring logger."""
|
25
17
|
|
26
18
|
_loggers: Dict[str, logging.Logger] = {}
|
19
|
+
_configured = False
|
27
20
|
|
28
21
|
@classmethod
|
29
22
|
def get_logger(cls, name: str = "django_cfg") -> logging.Logger:
|
30
|
-
"""
|
31
|
-
|
23
|
+
"""Get a configured logger instance."""
|
24
|
+
if not cls._configured:
|
25
|
+
cls._setup_logging()
|
32
26
|
|
33
|
-
Args:
|
34
|
-
name: Logger name (default: "django_cfg")
|
35
|
-
|
36
|
-
Returns:
|
37
|
-
Configured logger instance
|
38
|
-
"""
|
39
27
|
if name not in cls._loggers:
|
40
28
|
cls._loggers[name] = cls._create_logger(name)
|
41
29
|
return cls._loggers[name]
|
42
30
|
|
43
31
|
@classmethod
|
44
|
-
def
|
45
|
-
"""
|
32
|
+
def _setup_logging(cls):
|
33
|
+
"""Setup modular logging configuration with separate files per module."""
|
34
|
+
import os
|
35
|
+
current_dir = Path(os.getcwd())
|
36
|
+
logs_dir = current_dir / 'logs'
|
37
|
+
djangocfg_logs_dir = logs_dir / 'djangocfg'
|
38
|
+
|
39
|
+
# Create directories
|
40
|
+
logs_dir.mkdir(parents=True, exist_ok=True)
|
41
|
+
djangocfg_logs_dir.mkdir(parents=True, exist_ok=True)
|
42
|
+
|
43
|
+
print(f"[django-cfg] Setting up modular logging:")
|
44
|
+
print(f" Django logs: {logs_dir / 'django.log'}")
|
45
|
+
print(f" Django-CFG logs: {djangocfg_logs_dir}/")
|
46
|
+
|
47
|
+
# Get debug mode
|
46
48
|
try:
|
47
49
|
from django_cfg.core.config import get_current_config
|
48
50
|
config = get_current_config()
|
51
|
+
debug = config.debug if config else False
|
49
52
|
except Exception:
|
50
|
-
|
51
|
-
|
52
|
-
# Create logger
|
53
|
-
logger = logging.getLogger(name)
|
54
|
-
|
55
|
-
# Get logging configuration from config
|
56
|
-
log_level = logging.INFO
|
57
|
-
console_output = True
|
58
|
-
file_path = None
|
59
|
-
|
60
|
-
# Try to get logging config from DjangoConfig
|
61
|
-
if hasattr(config, 'logging') and config.logging:
|
62
|
-
logging_config = config.logging
|
63
|
-
log_level = getattr(logging, logging_config.level.upper(), logging.INFO)
|
64
|
-
console_output = logging_config.console_output
|
65
|
-
file_path = logging_config.file_path
|
53
|
+
debug = os.getenv('DEBUG', 'false').lower() in ('true', '1', 'yes')
|
66
54
|
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
55
|
+
# Create handlers
|
56
|
+
try:
|
57
|
+
# Handler for general Django logs
|
58
|
+
django_log_path = logs_dir / 'django.log'
|
59
|
+
django_handler = logging.FileHandler(django_log_path, encoding='utf-8')
|
60
|
+
django_handler.setLevel(logging.DEBUG if debug else logging.INFO)
|
61
|
+
|
62
|
+
# Console handler
|
75
63
|
console_handler = logging.StreamHandler()
|
76
|
-
console_handler.setLevel(
|
64
|
+
console_handler.setLevel(logging.DEBUG if debug else logging.INFO)
|
77
65
|
|
78
|
-
#
|
79
|
-
formatter =
|
66
|
+
# Set format for handlers
|
67
|
+
formatter = logging.Formatter('[%(asctime)s] %(levelname)s in %(name)s [%(filename)s:%(lineno)d]: %(message)s')
|
68
|
+
django_handler.setFormatter(formatter)
|
80
69
|
console_handler.setFormatter(formatter)
|
81
70
|
|
82
|
-
logger
|
83
|
-
|
84
|
-
|
85
|
-
if file_path:
|
86
|
-
file_path_obj = Path(file_path)
|
87
|
-
file_path_obj.parent.mkdir(parents=True, exist_ok=True)
|
71
|
+
# Configure root logger
|
72
|
+
root_logger = logging.getLogger()
|
73
|
+
root_logger.setLevel(logging.DEBUG if debug else logging.INFO)
|
88
74
|
|
89
|
-
|
90
|
-
|
75
|
+
# Clear existing handlers
|
76
|
+
root_logger.handlers.clear()
|
91
77
|
|
92
|
-
#
|
93
|
-
|
94
|
-
|
78
|
+
# Add handlers to root logger
|
79
|
+
root_logger.addHandler(console_handler)
|
80
|
+
root_logger.addHandler(django_handler) # All logs go to django.log
|
95
81
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
return logging.Formatter(format_str)
|
111
|
-
|
112
|
-
@classmethod
|
113
|
-
def _create_file_formatter(cls, config) -> logging.Formatter:
|
114
|
-
"""Create file formatter based on config."""
|
115
|
-
# Always detailed format for file logging
|
116
|
-
format_str = '[%(asctime)s] %(levelname)s in %(name)s [%(filename)s:%(lineno)d]: %(message)s'
|
117
|
-
return logging.Formatter(format_str)
|
82
|
+
print(f"[django-cfg] Modular logging configured successfully! Debug: {debug}")
|
83
|
+
cls._configured = True
|
84
|
+
|
85
|
+
except Exception as e:
|
86
|
+
print(f"[django-cfg] ERROR setting up modular logging: {e}")
|
87
|
+
# Fallback to console only
|
88
|
+
logging.basicConfig(
|
89
|
+
level=logging.DEBUG if debug else logging.INFO,
|
90
|
+
format='[%(asctime)s] %(levelname)s in %(name)s [%(filename)s:%(lineno)d]: %(message)s',
|
91
|
+
handlers=[logging.StreamHandler()],
|
92
|
+
force=True
|
93
|
+
)
|
94
|
+
cls._configured = True
|
118
95
|
|
119
96
|
@classmethod
|
120
|
-
def
|
121
|
-
"""
|
122
|
-
|
123
|
-
|
124
|
-
Returns:
|
125
|
-
Django LOGGING configuration dict
|
126
|
-
"""
|
127
|
-
try:
|
128
|
-
from django_cfg.core.config import get_current_config
|
129
|
-
config = get_current_config()
|
130
|
-
except Exception:
|
131
|
-
config = None
|
97
|
+
def _create_logger(cls, name: str) -> logging.Logger:
|
98
|
+
"""Create logger with modular file handling for django-cfg loggers."""
|
99
|
+
logger = logging.getLogger(name)
|
132
100
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
101
|
+
# If this is a django-cfg logger, add a specific file handler
|
102
|
+
if name.startswith('django_cfg'):
|
103
|
+
try:
|
104
|
+
import os
|
105
|
+
current_dir = Path(os.getcwd())
|
106
|
+
djangocfg_logs_dir = current_dir / 'logs' / 'djangocfg'
|
107
|
+
djangocfg_logs_dir.mkdir(parents=True, exist_ok=True)
|
108
|
+
|
109
|
+
# Extract module name from logger name
|
110
|
+
# e.g., 'django_cfg.payments.provider' -> 'payments'
|
111
|
+
# e.g., 'django_cfg.core' -> 'core'
|
112
|
+
# e.g., 'django_cfg' -> 'core'
|
113
|
+
parts = name.split('.')
|
114
|
+
if len(parts) > 1:
|
115
|
+
module_name = parts[1] # django_cfg.payments -> payments
|
116
|
+
else:
|
117
|
+
module_name = 'core' # django_cfg -> core
|
118
|
+
|
119
|
+
log_file_path = djangocfg_logs_dir / f'{module_name}.log'
|
120
|
+
|
121
|
+
# Create file handler for this specific module
|
122
|
+
file_handler = logging.FileHandler(log_file_path, encoding='utf-8')
|
123
|
+
|
124
|
+
# Get debug mode
|
125
|
+
try:
|
126
|
+
from django_cfg.core.config import get_current_config
|
127
|
+
config = get_current_config()
|
128
|
+
debug = config.debug if config else False
|
129
|
+
except Exception:
|
130
|
+
debug = os.getenv('DEBUG', 'false').lower() in ('true', '1', 'yes')
|
131
|
+
|
132
|
+
file_handler.setLevel(logging.DEBUG if debug else logging.INFO)
|
133
|
+
|
134
|
+
# Set format
|
135
|
+
formatter = logging.Formatter('[%(asctime)s] %(levelname)s in %(name)s [%(filename)s:%(lineno)d]: %(message)s')
|
136
|
+
file_handler.setFormatter(formatter)
|
137
|
+
|
138
|
+
# Add handler to logger
|
139
|
+
logger.addHandler(file_handler)
|
140
|
+
logger.propagate = True # Also send to parent (django.log)
|
141
|
+
|
142
|
+
print(f"[django-cfg] Created modular logger: {name} -> {log_file_path}")
|
143
|
+
|
144
|
+
except Exception as e:
|
145
|
+
print(f"[django-cfg] ERROR creating modular logger for {name}: {e}")
|
164
146
|
|
165
|
-
|
166
|
-
if hasattr(config, 'logging') and config.logging and config.logging.file_path:
|
167
|
-
logging_config['handlers']['file'] = {
|
168
|
-
'class': 'logging.FileHandler',
|
169
|
-
'filename': config.logging.file_path,
|
170
|
-
'formatter': 'verbose',
|
171
|
-
}
|
172
|
-
|
173
|
-
# Add file handler to root and django_cfg loggers
|
174
|
-
logging_config['root']['handlers'].append('file')
|
175
|
-
logging_config['loggers']['django_cfg']['handlers'].append('file')
|
176
|
-
|
177
|
-
return logging_config
|
147
|
+
return logger
|
178
148
|
|
179
149
|
|
180
150
|
# Convenience function for quick access
|
181
151
|
def get_logger(name: str = "django_cfg") -> logging.Logger:
|
182
152
|
"""
|
183
|
-
Get a configured logger instance.
|
153
|
+
Get a configured logger instance with automatic django-cfg prefix detection.
|
184
154
|
|
185
|
-
|
186
|
-
name: Logger name (default: "django_cfg")
|
187
|
-
|
188
|
-
Returns:
|
189
|
-
Configured logger instance
|
155
|
+
If called from django-cfg modules, automatically prefixes with 'django_cfg.'
|
190
156
|
"""
|
157
|
+
import inspect
|
158
|
+
|
159
|
+
# Auto-detect if we're being called from django-cfg code
|
160
|
+
if not name.startswith('django_cfg'):
|
161
|
+
# Get the calling frame to determine if we're in django-cfg code
|
162
|
+
frame = inspect.currentframe()
|
163
|
+
try:
|
164
|
+
# Go up the call stack to find the actual caller
|
165
|
+
caller_frame = frame.f_back
|
166
|
+
if caller_frame:
|
167
|
+
caller_filename = caller_frame.f_code.co_filename
|
168
|
+
|
169
|
+
# Check if caller is from django-cfg modules
|
170
|
+
if '/django_cfg/' in caller_filename:
|
171
|
+
# Extract module path from filename
|
172
|
+
# e.g., /path/to/django_cfg/apps/payments/services/providers/registry.py
|
173
|
+
# -> django_cfg.payments.providers
|
174
|
+
|
175
|
+
parts = caller_filename.split('/django_cfg/')
|
176
|
+
if len(parts) > 1:
|
177
|
+
module_path = parts[1] # apps/payments/services/providers/registry.py
|
178
|
+
|
179
|
+
# Convert path to module name
|
180
|
+
if module_path.startswith('apps/'):
|
181
|
+
# apps/payments/services/providers/registry.py -> payments.providers
|
182
|
+
path_parts = module_path.split('/')[1:] # Remove 'apps'
|
183
|
+
if path_parts:
|
184
|
+
# Remove file extension and 'services' if present
|
185
|
+
clean_parts = []
|
186
|
+
for part in path_parts[:-1]: # Exclude filename
|
187
|
+
if part not in ['services', 'management', 'commands']:
|
188
|
+
clean_parts.append(part)
|
189
|
+
|
190
|
+
if clean_parts:
|
191
|
+
auto_name = f"django_cfg.{'.'.join(clean_parts)}"
|
192
|
+
print(f"[django-cfg] Auto-detected logger name: {name} -> {auto_name}")
|
193
|
+
name = auto_name
|
194
|
+
|
195
|
+
elif module_path.startswith('modules/'):
|
196
|
+
# modules/django_logger.py -> django_cfg.core
|
197
|
+
name = "django_cfg.core"
|
198
|
+
|
199
|
+
elif module_path.startswith('core/'):
|
200
|
+
# core/config.py -> django_cfg.core
|
201
|
+
name = "django_cfg.core"
|
202
|
+
finally:
|
203
|
+
del frame
|
204
|
+
|
191
205
|
return DjangoLogger.get_logger(name)
|
192
206
|
|
193
207
|
|
194
208
|
# Export public API
|
195
|
-
__all__ = ['DjangoLogger', 'get_logger']
|
209
|
+
__all__ = ['DjangoLogger', 'get_logger']
|
@@ -145,7 +145,7 @@ class DashboardManager(BaseCfgModule):
|
|
145
145
|
collapsible=True,
|
146
146
|
items=[
|
147
147
|
NavigationItem(title="Task Queue", icon=Icons.QUEUE, link="/admin/django_dramatiq/task/"),
|
148
|
-
NavigationItem(title="Task Dashboard", icon=Icons.SETTINGS_APPLICATIONS, link="/cfg/
|
148
|
+
NavigationItem(title="Task Dashboard", icon=Icons.SETTINGS_APPLICATIONS, link="/cfg/admin/django_cfg_tasks/admin/dashboard/"),
|
149
149
|
]
|
150
150
|
))
|
151
151
|
|
@@ -165,21 +165,74 @@ class DashboardManager(BaseCfgModule):
|
|
165
165
|
|
166
166
|
# Add Payments section if enabled
|
167
167
|
if self.is_payments_enabled():
|
168
|
+
try:
|
169
|
+
from django_cfg.models.payments import PaymentsConfig
|
170
|
+
config = PaymentsConfig.get_current_config()
|
171
|
+
|
172
|
+
payments_items = []
|
173
|
+
|
174
|
+
# Main dashboard (always show if payments app enabled)
|
175
|
+
payments_items.append(
|
176
|
+
NavigationItem(title="Payment Dashboard", icon=Icons.DASHBOARD, link="/cfg/admin/django_cfg_payments/admin/")
|
177
|
+
)
|
178
|
+
|
179
|
+
# Always show basic admin models (even if payments functionality is disabled)
|
180
|
+
payments_items.extend([
|
181
|
+
NavigationItem(title="Payments", icon=Icons.ACCOUNT_BALANCE, link="/admin/payments/universalpayment/"),
|
182
|
+
NavigationItem(title="Currencies", icon=Icons.CURRENCY_BITCOIN, link="/admin/payments/currency/"),
|
183
|
+
NavigationItem(title="Currency Networks", icon=Icons.LINK, link="/admin/payments/network/"),
|
184
|
+
NavigationItem(title="Provider Currencies", icon=Icons.ACCOUNT_CIRCLE, link="/admin/payments/providercurrency/"),
|
185
|
+
])
|
186
|
+
|
187
|
+
# Add advanced features only if payments functionality is enabled
|
188
|
+
if config.enabled:
|
189
|
+
payments_items.append(
|
190
|
+
NavigationItem(title="Webhook Dashboard", icon=Icons.WEBHOOK, link="/cfg/admin/django_cfg_payments/admin/webhooks/")
|
191
|
+
)
|
192
|
+
payments_items.append(
|
193
|
+
NavigationItem(title="Create Payment", icon=Icons.ADD, link="/cfg/admin/django_cfg_payments/admin/payments/create/")
|
194
|
+
)
|
195
|
+
payments_items.append(
|
196
|
+
NavigationItem(title="Currency Converter", icon=Icons.CURRENCY_EXCHANGE, link="/cfg/admin/django_cfg_payments/admin/tools/converter/")
|
197
|
+
)
|
198
|
+
|
199
|
+
# Show subscription features only if enabled
|
200
|
+
if config.show_subscription_management():
|
201
|
+
payments_items.extend([
|
202
|
+
NavigationItem(title="Subscriptions", icon=Icons.PERSON_ADD, link="/admin/payments/subscription/"),
|
203
|
+
NavigationItem(title="Tariffs", icon=Icons.PRICE_CHANGE, link="/admin/payments/tariff/"),
|
204
|
+
])
|
205
|
+
|
206
|
+
# Show API management only if enabled
|
207
|
+
if config.show_api_management():
|
208
|
+
payments_items.extend([
|
209
|
+
NavigationItem(title="API Keys", icon=Icons.KEY, link="/admin/payments/apikey/"),
|
210
|
+
NavigationItem(title="Endpoint Groups", icon=Icons.GROUP, link="/admin/payments/endpointgroup/"),
|
211
|
+
])
|
212
|
+
|
213
|
+
# Show balance/transaction features only if enabled
|
214
|
+
if config.show_balance_management():
|
215
|
+
payments_items.append(
|
216
|
+
NavigationItem(title="Balances", icon=Icons.ACCOUNT_BALANCE_WALLET, link="/admin/payments/userbalance/")
|
217
|
+
)
|
218
|
+
|
219
|
+
if config.show_transaction_history():
|
220
|
+
payments_items.append(
|
221
|
+
NavigationItem(title="Transactions", icon=Icons.RECEIPT_LONG, link="/admin/payments/transaction/")
|
222
|
+
)
|
223
|
+
|
224
|
+
except Exception:
|
225
|
+
# Fallback
|
226
|
+
payments_items = [
|
227
|
+
NavigationItem(title="Payment Dashboard", icon=Icons.DASHBOARD, link="/cfg/admin/django_cfg_payments/admin/"),
|
228
|
+
NavigationItem(title="Payments", icon=Icons.ACCOUNT_BALANCE, link="/admin/payments/universalpayment/"),
|
229
|
+
]
|
230
|
+
|
168
231
|
navigation_sections.append(NavigationSection(
|
169
232
|
title="Payments",
|
170
233
|
separator=True,
|
171
234
|
collapsible=True,
|
172
|
-
items=
|
173
|
-
NavigationItem(title="Payments", icon=Icons.ACCOUNT_BALANCE, link="/admin/django_cfg_payments/universalpayment/"),
|
174
|
-
NavigationItem(title="Subscriptions", icon=Icons.PERSON_ADD, link="/admin/django_cfg_payments/subscription/"),
|
175
|
-
NavigationItem(title="API Keys", icon=Icons.KEY, link="/admin/django_cfg_payments/apikey/"),
|
176
|
-
NavigationItem(title="Balances", icon=Icons.ACCOUNT_BALANCE_WALLET, link="/admin/django_cfg_payments/userbalance/"),
|
177
|
-
NavigationItem(title="Transactions", icon=Icons.DESCRIPTION, link="/admin/django_cfg_payments/transaction/"),
|
178
|
-
NavigationItem(title="Currencies", icon=Icons.ACCOUNT_CIRCLE, link="/admin/django_cfg_payments/currency/"),
|
179
|
-
NavigationItem(title="Currency Networks", icon=Icons.LINK, link="/admin/django_cfg_payments/currencynetwork/"),
|
180
|
-
NavigationItem(title="Endpoint Groups", icon=Icons.GROUP, link="/admin/django_cfg_payments/endpointgroup/"),
|
181
|
-
NavigationItem(title="Tariffs", icon=Icons.SETTINGS, link="/admin/django_cfg_payments/tariff/"),
|
182
|
-
]
|
235
|
+
items=payments_items
|
183
236
|
))
|
184
237
|
|
185
238
|
# Convert all NavigationSection objects to dictionaries
|
django_cfg/registry/core.py
CHANGED
@@ -5,6 +5,7 @@ Core Django-CFG components registry.
|
|
5
5
|
CORE_REGISTRY = {
|
6
6
|
# Core configuration
|
7
7
|
"DjangoConfig": ("django_cfg.core.config", "DjangoConfig"),
|
8
|
+
"StartupInfoMode": ("django_cfg.core.config", "StartupInfoMode"),
|
8
9
|
|
9
10
|
# Core exceptions
|
10
11
|
"ConfigurationError": ("django_cfg.core.exceptions", "ConfigurationError"),
|
Binary file
|
@@ -1,26 +1,26 @@
|
|
1
1
|
{% load unfold %}
|
2
2
|
|
3
3
|
<!-- Action Grid Component -->
|
4
|
-
<div class="grid grid-cols-1
|
4
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
5
5
|
{% for action in actions %}
|
6
6
|
<a href="{{ action.link }}"
|
7
|
-
class="group flex items-center p-4
|
7
|
+
class="group flex items-center p-4 theme-card rounded-lg border theme-border hover:border-blue-600 dark:hover:border-blue-500 hover:shadow-md transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
|
8
8
|
|
9
9
|
<!-- Icon -->
|
10
10
|
<div class="flex-shrink-0 mr-4">
|
11
11
|
<div class="p-2 rounded-lg transition-colors duration-200
|
12
|
-
{% if action.color == 'primary' %}bg-
|
12
|
+
{% if action.color == 'primary' %}bg-blue-100 dark:bg-blue-900/20 group-hover:bg-blue-200 dark:group-hover:bg-blue-800/30
|
13
13
|
{% elif action.color == 'success' %}bg-green-100 dark:bg-green-900/20 group-hover:bg-green-200 dark:group-hover:bg-green-800/30
|
14
14
|
{% elif action.color == 'warning' %}bg-amber-100 dark:bg-amber-900/20 group-hover:bg-amber-200 dark:group-hover:bg-amber-800/30
|
15
15
|
{% elif action.color == 'danger' %}bg-red-100 dark:bg-red-900/20 group-hover:bg-red-200 dark:group-hover:bg-red-800/30
|
16
|
-
{% else %}bg-
|
16
|
+
{% else %}bg-gray-100 dark:bg-gray-800 group-hover:bg-gray-200 dark:group-hover:bg-gray-700{% endif %}">
|
17
17
|
|
18
18
|
<span class="material-icons text-lg
|
19
|
-
{% if action.color == 'primary' %}text-
|
19
|
+
{% if action.color == 'primary' %}text-blue-600 dark:text-blue-400
|
20
20
|
{% elif action.color == 'success' %}text-green-600 dark:text-green-400
|
21
21
|
{% elif action.color == 'warning' %}text-amber-600 dark:text-amber-400
|
22
22
|
{% elif action.color == 'danger' %}text-red-600 dark:text-red-400
|
23
|
-
{% else %}text-
|
23
|
+
{% else %}text-gray-600 dark:text-gray-400{% endif %}">
|
24
24
|
{{ action.icon }}
|
25
25
|
</span>
|
26
26
|
</div>
|
@@ -28,11 +28,11 @@
|
|
28
28
|
|
29
29
|
<!-- Content -->
|
30
30
|
<div class="flex-1 min-w-0">
|
31
|
-
<h3 class="text-sm font-medium
|
31
|
+
<h3 class="text-sm font-medium theme-text group-hover:text-blue-600 dark:group-hover:text-blue-500 transition-colors duration-200">
|
32
32
|
{{ action.title }}
|
33
33
|
</h3>
|
34
34
|
{% if action.description %}
|
35
|
-
<p class="text-xs text-
|
35
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1 line-clamp-2">
|
36
36
|
{{ action.description }}
|
37
37
|
</p>
|
38
38
|
{% endif %}
|
@@ -40,7 +40,7 @@
|
|
40
40
|
|
41
41
|
<!-- Arrow -->
|
42
42
|
<div class="flex-shrink-0 ml-2">
|
43
|
-
<span class="material-icons text-
|
43
|
+
<span class="material-icons text-gray-400 dark:text-gray-500 group-hover:text-blue-600 dark:group-hover:text-blue-500 transition-colors duration-200">
|
44
44
|
arrow_forward
|
45
45
|
</span>
|
46
46
|
</div>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
{% load unfold %}
|
2
2
|
|
3
3
|
<!-- Metric Card Component -->
|
4
|
-
<div class="
|
4
|
+
<div class="theme-card rounded-lg p-5 border theme-border hover:shadow-md transition-shadow duration-200">
|
5
5
|
<div class="flex items-center justify-between">
|
6
6
|
<div class="flex items-center space-x-3">
|
7
7
|
<div class="flex-shrink-0">
|
@@ -10,16 +10,16 @@
|
|
10
10
|
{% elif status == 'warning' %}text-amber-600 dark:text-amber-400
|
11
11
|
{% elif status == 'error' or status == 'failed' %}text-red-600 dark:text-red-400
|
12
12
|
{% elif status == 'info' %}text-blue-600 dark:text-blue-400
|
13
|
-
{% else %}text-
|
13
|
+
{% else %}text-blue-600 dark:text-blue-400{% endif %}">
|
14
14
|
{{ icon }}
|
15
15
|
</span>
|
16
16
|
</div>
|
17
|
-
<div>
|
18
|
-
<div class="text-sm font-medium text
|
17
|
+
<div class="min-w-0 flex-1">
|
18
|
+
<div class="text-sm font-medium theme-text truncate">
|
19
19
|
{{ title }}
|
20
20
|
</div>
|
21
21
|
{% if description %}
|
22
|
-
<div class="text-xs text-
|
22
|
+
<div class="text-xs text-gray-500 dark:text-gray-400 mt-1 truncate">
|
23
23
|
{{ description }}
|
24
24
|
</div>
|
25
25
|
{% endif %}
|
@@ -1,12 +1,12 @@
|
|
1
1
|
{% load unfold %}
|
2
2
|
|
3
3
|
<!-- Status Badge Component -->
|
4
|
-
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
4
|
+
<span class="status-badge inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
5
5
|
{% if status == 'active' or status == 'healthy' or status == 'success' %}bg-green-100 dark:bg-green-900/20 text-green-600 dark:text-green-400
|
6
6
|
{% elif status == 'warning' or status == 'pending' %}bg-amber-100 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400
|
7
7
|
{% elif status == 'error' or status == 'failed' or status == 'inactive' %}bg-red-100 dark:bg-red-900/20 text-red-600 dark:text-red-400
|
8
8
|
{% elif status == 'info' or status == 'processing' %}bg-blue-100 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400
|
9
|
-
{% else %}bg-
|
9
|
+
{% else %}bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400{% endif %}">
|
10
10
|
|
11
11
|
{% if icon %}
|
12
12
|
<span class="material-icons text-xs mr-1">{{ icon }}</span>
|