django-cfg 1.2.22__py3-none-any.whl → 1.2.25__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/knowbase/tasks/archive_tasks.py +6 -6
- django_cfg/apps/knowbase/tasks/document_processing.py +3 -3
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +2 -2
- django_cfg/apps/knowbase/tasks/maintenance.py +3 -3
- django_cfg/apps/payments/admin/__init__.py +23 -0
- django_cfg/apps/payments/admin/api_keys_admin.py +347 -0
- django_cfg/apps/payments/admin/balance_admin.py +434 -0
- django_cfg/apps/payments/admin/currencies_admin.py +186 -0
- django_cfg/apps/payments/admin/filters.py +259 -0
- django_cfg/apps/payments/admin/payments_admin.py +142 -0
- django_cfg/apps/payments/admin/subscriptions_admin.py +227 -0
- django_cfg/apps/payments/admin/tariffs_admin.py +199 -0
- django_cfg/apps/payments/config/__init__.py +65 -0
- django_cfg/apps/payments/config/module.py +70 -0
- django_cfg/apps/payments/config/providers.py +115 -0
- django_cfg/apps/payments/config/settings.py +96 -0
- django_cfg/apps/payments/config/utils.py +52 -0
- django_cfg/apps/payments/decorators.py +291 -0
- django_cfg/apps/payments/management/__init__.py +3 -0
- django_cfg/apps/payments/management/commands/README.md +178 -0
- django_cfg/apps/payments/management/commands/__init__.py +3 -0
- django_cfg/apps/payments/management/commands/currency_stats.py +323 -0
- django_cfg/apps/payments/management/commands/populate_currencies.py +246 -0
- django_cfg/apps/payments/management/commands/update_currencies.py +336 -0
- django_cfg/apps/payments/managers/currency_manager.py +65 -14
- django_cfg/apps/payments/middleware/api_access.py +294 -0
- django_cfg/apps/payments/middleware/rate_limiting.py +216 -0
- django_cfg/apps/payments/middleware/usage_tracking.py +296 -0
- django_cfg/apps/payments/migrations/0001_initial.py +125 -11
- django_cfg/apps/payments/models/__init__.py +18 -0
- django_cfg/apps/payments/models/api_keys.py +2 -2
- django_cfg/apps/payments/models/balance.py +2 -2
- django_cfg/apps/payments/models/base.py +16 -0
- django_cfg/apps/payments/models/events.py +2 -2
- django_cfg/apps/payments/models/payments.py +112 -2
- django_cfg/apps/payments/models/subscriptions.py +2 -2
- django_cfg/apps/payments/services/__init__.py +64 -7
- django_cfg/apps/payments/services/billing/__init__.py +8 -0
- django_cfg/apps/payments/services/cache/__init__.py +15 -0
- django_cfg/apps/payments/services/cache/base.py +30 -0
- django_cfg/apps/payments/services/cache/simple_cache.py +135 -0
- django_cfg/apps/payments/services/core/__init__.py +17 -0
- django_cfg/apps/payments/services/core/balance_service.py +447 -0
- django_cfg/apps/payments/services/core/fallback_service.py +432 -0
- django_cfg/apps/payments/services/core/payment_service.py +576 -0
- django_cfg/apps/payments/services/core/subscription_service.py +614 -0
- django_cfg/apps/payments/services/internal_types.py +297 -0
- django_cfg/apps/payments/services/middleware/__init__.py +8 -0
- django_cfg/apps/payments/services/monitoring/__init__.py +22 -0
- django_cfg/apps/payments/services/monitoring/api_schemas.py +222 -0
- django_cfg/apps/payments/services/monitoring/provider_health.py +372 -0
- django_cfg/apps/payments/services/providers/__init__.py +22 -0
- django_cfg/apps/payments/services/providers/base.py +137 -0
- django_cfg/apps/payments/services/providers/cryptapi.py +273 -0
- django_cfg/apps/payments/services/providers/cryptomus.py +310 -0
- django_cfg/apps/payments/services/providers/nowpayments.py +293 -0
- django_cfg/apps/payments/services/providers/registry.py +103 -0
- django_cfg/apps/payments/services/security/__init__.py +34 -0
- django_cfg/apps/payments/services/security/error_handler.py +637 -0
- django_cfg/apps/payments/services/security/payment_notifications.py +342 -0
- django_cfg/apps/payments/services/security/webhook_validator.py +475 -0
- django_cfg/apps/payments/services/validators/__init__.py +8 -0
- django_cfg/apps/payments/signals/__init__.py +13 -0
- django_cfg/apps/payments/signals/api_key_signals.py +160 -0
- django_cfg/apps/payments/signals/payment_signals.py +128 -0
- django_cfg/apps/payments/signals/subscription_signals.py +196 -0
- django_cfg/apps/payments/tasks/__init__.py +12 -0
- django_cfg/apps/payments/tasks/webhook_processing.py +177 -0
- django_cfg/apps/payments/urls.py +5 -5
- django_cfg/apps/payments/utils/__init__.py +45 -0
- django_cfg/apps/payments/utils/billing_utils.py +342 -0
- django_cfg/apps/payments/utils/config_utils.py +245 -0
- django_cfg/apps/payments/utils/middleware_utils.py +228 -0
- django_cfg/apps/payments/utils/validation_utils.py +94 -0
- django_cfg/apps/payments/views/payment_views.py +40 -2
- django_cfg/apps/payments/views/webhook_views.py +266 -0
- django_cfg/apps/payments/viewsets.py +65 -0
- django_cfg/apps/support/signals.py +16 -4
- django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
- django_cfg/cli/README.md +2 -2
- django_cfg/cli/commands/create_project.py +1 -1
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/cli/main.py +1 -1
- django_cfg/cli/utils.py +5 -5
- django_cfg/core/config.py +18 -4
- django_cfg/models/payments.py +546 -0
- django_cfg/models/revolution.py +1 -1
- django_cfg/models/tasks.py +51 -2
- django_cfg/modules/base.py +12 -6
- django_cfg/modules/django_currency/README.md +104 -269
- django_cfg/modules/django_currency/__init__.py +99 -41
- django_cfg/modules/django_currency/clients/__init__.py +11 -0
- django_cfg/modules/django_currency/clients/coingecko_client.py +257 -0
- django_cfg/modules/django_currency/clients/yfinance_client.py +246 -0
- django_cfg/modules/django_currency/core/__init__.py +42 -0
- django_cfg/modules/django_currency/core/converter.py +169 -0
- django_cfg/modules/django_currency/core/exceptions.py +28 -0
- django_cfg/modules/django_currency/core/models.py +54 -0
- django_cfg/modules/django_currency/database/__init__.py +25 -0
- django_cfg/modules/django_currency/database/database_loader.py +507 -0
- django_cfg/modules/django_currency/utils/__init__.py +9 -0
- django_cfg/modules/django_currency/utils/cache.py +92 -0
- django_cfg/modules/django_email.py +42 -4
- django_cfg/modules/django_unfold/dashboard.py +20 -0
- django_cfg/registry/core.py +10 -0
- django_cfg/template_archive/__init__.py +0 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/METADATA +11 -6
- {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/RECORD +113 -50
- django_cfg/apps/agents/examples/__init__.py +0 -3
- django_cfg/apps/agents/examples/simple_example.py +0 -161
- django_cfg/apps/knowbase/examples/__init__.py +0 -3
- django_cfg/apps/knowbase/examples/external_data_usage.py +0 -191
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +0 -199
- django_cfg/apps/payments/services/base.py +0 -68
- django_cfg/apps/payments/services/nowpayments.py +0 -78
- django_cfg/apps/payments/services/providers.py +0 -77
- django_cfg/apps/payments/services/redis_service.py +0 -215
- django_cfg/modules/django_currency/cache.py +0 -430
- django_cfg/modules/django_currency/converter.py +0 -324
- django_cfg/modules/django_currency/service.py +0 -277
- {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/licenses/LICENSE +0 -0
@@ -2,6 +2,8 @@ from django.db.models.signals import post_save
|
|
2
2
|
from django.dispatch import receiver
|
3
3
|
import traceback
|
4
4
|
import logging
|
5
|
+
import socket
|
6
|
+
from smtplib import SMTPException
|
5
7
|
|
6
8
|
from .models import Message, Ticket
|
7
9
|
from .utils.support_email_service import SupportEmailService
|
@@ -10,7 +12,7 @@ from django_cfg.modules.django_telegram import DjangoTelegram
|
|
10
12
|
logger = logging.getLogger(__name__)
|
11
13
|
|
12
14
|
@receiver(post_save, sender=Message)
|
13
|
-
def notify_on_message(sender, instance, created, **kwargs):
|
15
|
+
def notify_on_message(sender, instance: Message, created: bool, **kwargs):
|
14
16
|
"""Send notifications when a new message is created."""
|
15
17
|
logger.info(f"🔔 Signal triggered: Message {instance.uuid} created={created}")
|
16
18
|
|
@@ -32,9 +34,14 @@ def notify_on_message(sender, instance, created, **kwargs):
|
|
32
34
|
email_service = SupportEmailService(user)
|
33
35
|
email_service.send_support_reply_email(instance)
|
34
36
|
logger.info(f" 📬 Email sent successfully!")
|
37
|
+
except (socket.timeout, TimeoutError, SMTPException) as e:
|
38
|
+
logger.warning(f" ⚠️ Email service timeout/error: {e}")
|
39
|
+
logger.info(f" 📝 Message processed successfully, email notification failed")
|
40
|
+
# Do not re-raise to prevent blocking the main process
|
35
41
|
except Exception as e:
|
36
42
|
logger.error(f" ❌ Failed to send email notification: {e}")
|
37
|
-
traceback.
|
43
|
+
logger.debug(f" 🔍 Exception details: {traceback.format_exc()}")
|
44
|
+
# Do not re-raise to prevent blocking the main process
|
38
45
|
else:
|
39
46
|
logger.info(f" ⏭️ Not sending email (staff: {instance.sender.is_staff}, from_author: {instance.is_from_author})")
|
40
47
|
|
@@ -60,7 +67,7 @@ def notify_on_message(sender, instance, created, **kwargs):
|
|
60
67
|
|
61
68
|
|
62
69
|
@receiver(post_save, sender=Ticket)
|
63
|
-
def notify_on_ticket_created(sender, instance, created, **kwargs):
|
70
|
+
def notify_on_ticket_created(sender, instance: Ticket, created: bool, **kwargs):
|
64
71
|
"""Send notification when a new ticket is created."""
|
65
72
|
if not created:
|
66
73
|
return
|
@@ -68,5 +75,10 @@ def notify_on_ticket_created(sender, instance, created, **kwargs):
|
|
68
75
|
try:
|
69
76
|
email_service = SupportEmailService(instance.user)
|
70
77
|
email_service.send_ticket_created_email(instance)
|
78
|
+
logger.info(f" 📬 Ticket creation email sent successfully!")
|
79
|
+
except (socket.timeout, TimeoutError, SMTPException) as e:
|
80
|
+
logger.warning(f" ⚠️ Email service timeout/error for ticket creation: {e}")
|
81
|
+
logger.info(f" 📝 Ticket created successfully, email notification failed")
|
71
82
|
except Exception as e:
|
72
|
-
logger.error(f"Failed to send ticket creation email: {e}")
|
83
|
+
logger.error(f" ❌ Failed to send ticket creation email: {e}")
|
84
|
+
logger.debug(f" 🔍 Exception details: {traceback.format_exc()}")
|
@@ -197,7 +197,7 @@
|
|
197
197
|
submitBtn.disabled = true;
|
198
198
|
|
199
199
|
try {
|
200
|
-
const response = await fetch(`{% url 'send-message-ajax' ticket_uuid=ticket.uuid %}`, {
|
200
|
+
const response = await fetch(`{% url 'cfg_support:send-message-ajax' ticket_uuid=ticket.uuid %}`, {
|
201
201
|
method: 'POST',
|
202
202
|
headers: {
|
203
203
|
'Content-Type': 'application/json',
|
django_cfg/cli/README.md
CHANGED
@@ -506,9 +506,9 @@ print(f"Django installed: {deps['django']}")
|
|
506
506
|
## 📚 Documentation
|
507
507
|
|
508
508
|
- **Django CFG**: https://djangocfg.com
|
509
|
-
- **GitHub**: https://github.com/
|
509
|
+
- **GitHub**: https://github.com/markolofsen/django-cfg
|
510
510
|
- **PyPI**: https://pypi.org/project/django-cfg/
|
511
|
-
- **Examples**: https://github.com/
|
511
|
+
- **Examples**: https://github.com/markolofsen/django-cfg/tree/main/examples
|
512
512
|
|
513
513
|
## 📄 License
|
514
514
|
|
@@ -257,7 +257,7 @@ python manage.py translate_content
|
|
257
257
|
## 🤝 Contributing
|
258
258
|
|
259
259
|
This project uses **django-cfg** for configuration management.
|
260
|
-
For more information, visit: [https://github.com/
|
260
|
+
For more information, visit: [https://github.com/markolofsen/django-cfg](https://github.com/markolofsen/django-cfg)
|
261
261
|
|
262
262
|
## 📄 License
|
263
263
|
|
django_cfg/cli/commands/info.py
CHANGED
@@ -120,7 +120,7 @@ def info(verbose: bool):
|
|
120
120
|
click.echo(" pip install twilio sendgrid django-unfold")
|
121
121
|
click.echo()
|
122
122
|
click.echo("📚 Documentation: https://djangocfg.com")
|
123
|
-
click.echo("🐙 GitHub: https://github.com/
|
123
|
+
click.echo("🐙 GitHub: https://github.com/markolofsen/django-cfg")
|
124
124
|
|
125
125
|
# Warnings for missing critical dependencies
|
126
126
|
missing_critical = [dep for dep in ["django", "pydantic"] if not deps.get(dep, False)]
|
django_cfg/cli/main.py
CHANGED
@@ -11,7 +11,7 @@ from typing import Optional
|
|
11
11
|
from .commands.create_project import create_project
|
12
12
|
from .commands.info import info
|
13
13
|
from .utils import get_package_info
|
14
|
-
from ..version_check import check_python_version
|
14
|
+
from ..utils.version_check import check_python_version
|
15
15
|
|
16
16
|
|
17
17
|
@click.group(name="django-cfg")
|
django_cfg/cli/utils.py
CHANGED
@@ -48,15 +48,15 @@ def find_template_archive() -> Optional[Path]:
|
|
48
48
|
import django_cfg
|
49
49
|
package_path = Path(django_cfg.__file__).parent
|
50
50
|
|
51
|
-
# Method 1: Package
|
52
|
-
search_paths.append(package_path / "
|
51
|
+
# Method 1: Package template_archive directory
|
52
|
+
search_paths.append(package_path / "template_archive" / "django_sample.zip")
|
53
53
|
|
54
54
|
# Method 2: Site-packages shared data
|
55
55
|
site_packages = Path(sysconfig.get_paths()["purelib"])
|
56
|
-
search_paths.append(site_packages / "django_cfg" / "
|
56
|
+
search_paths.append(site_packages / "django_cfg" / "template_archive" / "django_sample.zip")
|
57
57
|
|
58
58
|
# Method 3: Development installation - src directory
|
59
|
-
dev_path = package_path.parent.parent / "src" / "django_cfg" / "
|
59
|
+
dev_path = package_path.parent.parent / "src" / "django_cfg" / "template_archive" / "django_sample.zip"
|
60
60
|
search_paths.append(dev_path)
|
61
61
|
|
62
62
|
except ImportError:
|
@@ -64,7 +64,7 @@ def find_template_archive() -> Optional[Path]:
|
|
64
64
|
|
65
65
|
# Method 4: Relative to CLI files (development)
|
66
66
|
cli_path = Path(__file__).parent.parent.parent.parent
|
67
|
-
search_paths.append(cli_path / "src" / "django_cfg" / "
|
67
|
+
search_paths.append(cli_path / "src" / "django_cfg" / "template_archive" / "django_sample.zip")
|
68
68
|
|
69
69
|
# Return first existing path
|
70
70
|
for path in search_paths:
|
django_cfg/core/config.py
CHANGED
@@ -21,6 +21,7 @@ from django_cfg import (
|
|
21
21
|
UnfoldConfig, DRFConfig, SpectacularConfig, LimitsConfig
|
22
22
|
)
|
23
23
|
from django_cfg.models.tasks import TaskConfig
|
24
|
+
from django_cfg.models.payments import PaymentsConfig
|
24
25
|
|
25
26
|
# Default apps
|
26
27
|
DEFAULT_APPS = [
|
@@ -158,9 +159,10 @@ class DjangoConfig(BaseModel):
|
|
158
159
|
default=False,
|
159
160
|
description="Enable django-cfg Maintenance application (multi-site maintenance mode with Cloudflare)",
|
160
161
|
)
|
161
|
-
|
162
|
-
|
163
|
-
|
162
|
+
# === Payment System Configuration ===
|
163
|
+
payments: Optional[PaymentsConfig] = Field(
|
164
|
+
default=None,
|
165
|
+
description="Universal payment system configuration (providers, subscriptions, API keys, billing)",
|
164
166
|
)
|
165
167
|
|
166
168
|
# === URLs ===
|
@@ -564,6 +566,14 @@ class DjangoConfig(BaseModel):
|
|
564
566
|
if self.enable_knowbase or self.enable_agents:
|
565
567
|
return True
|
566
568
|
|
569
|
+
# Check if payments module requires tasks
|
570
|
+
if self.payments and self.payments.should_enable_tasks():
|
571
|
+
return True
|
572
|
+
|
573
|
+
# Check if agents module requires tasks
|
574
|
+
if self.enable_agents:
|
575
|
+
return True
|
576
|
+
|
567
577
|
return False
|
568
578
|
|
569
579
|
def get_installed_apps(self) -> List[str]:
|
@@ -597,7 +607,7 @@ class DjangoConfig(BaseModel):
|
|
597
607
|
apps.append("django_cfg.apps.agents")
|
598
608
|
if self.enable_maintenance:
|
599
609
|
apps.append("django_cfg.apps.maintenance")
|
600
|
-
if self.
|
610
|
+
if self.payments and self.payments.enabled:
|
601
611
|
apps.append("django_cfg.apps.payments")
|
602
612
|
|
603
613
|
# Auto-enable tasks if needed
|
@@ -694,6 +704,10 @@ class DjangoConfig(BaseModel):
|
|
694
704
|
if self.enable_accounts:
|
695
705
|
middleware.append("django_cfg.middleware.UserActivityMiddleware")
|
696
706
|
|
707
|
+
# Add payments middleware if enabled
|
708
|
+
if self.payments and self.payments.enabled:
|
709
|
+
middleware.extend(self.payments.get_middleware_classes())
|
710
|
+
|
697
711
|
# Add custom middleware
|
698
712
|
middleware.extend(self.custom_middleware)
|
699
713
|
|