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.
Files changed (125) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/knowbase/tasks/archive_tasks.py +6 -6
  3. django_cfg/apps/knowbase/tasks/document_processing.py +3 -3
  4. django_cfg/apps/knowbase/tasks/external_data_tasks.py +2 -2
  5. django_cfg/apps/knowbase/tasks/maintenance.py +3 -3
  6. django_cfg/apps/payments/admin/__init__.py +23 -0
  7. django_cfg/apps/payments/admin/api_keys_admin.py +347 -0
  8. django_cfg/apps/payments/admin/balance_admin.py +434 -0
  9. django_cfg/apps/payments/admin/currencies_admin.py +186 -0
  10. django_cfg/apps/payments/admin/filters.py +259 -0
  11. django_cfg/apps/payments/admin/payments_admin.py +142 -0
  12. django_cfg/apps/payments/admin/subscriptions_admin.py +227 -0
  13. django_cfg/apps/payments/admin/tariffs_admin.py +199 -0
  14. django_cfg/apps/payments/config/__init__.py +65 -0
  15. django_cfg/apps/payments/config/module.py +70 -0
  16. django_cfg/apps/payments/config/providers.py +115 -0
  17. django_cfg/apps/payments/config/settings.py +96 -0
  18. django_cfg/apps/payments/config/utils.py +52 -0
  19. django_cfg/apps/payments/decorators.py +291 -0
  20. django_cfg/apps/payments/management/__init__.py +3 -0
  21. django_cfg/apps/payments/management/commands/README.md +178 -0
  22. django_cfg/apps/payments/management/commands/__init__.py +3 -0
  23. django_cfg/apps/payments/management/commands/currency_stats.py +323 -0
  24. django_cfg/apps/payments/management/commands/populate_currencies.py +246 -0
  25. django_cfg/apps/payments/management/commands/update_currencies.py +336 -0
  26. django_cfg/apps/payments/managers/currency_manager.py +65 -14
  27. django_cfg/apps/payments/middleware/api_access.py +294 -0
  28. django_cfg/apps/payments/middleware/rate_limiting.py +216 -0
  29. django_cfg/apps/payments/middleware/usage_tracking.py +296 -0
  30. django_cfg/apps/payments/migrations/0001_initial.py +125 -11
  31. django_cfg/apps/payments/models/__init__.py +18 -0
  32. django_cfg/apps/payments/models/api_keys.py +2 -2
  33. django_cfg/apps/payments/models/balance.py +2 -2
  34. django_cfg/apps/payments/models/base.py +16 -0
  35. django_cfg/apps/payments/models/events.py +2 -2
  36. django_cfg/apps/payments/models/payments.py +112 -2
  37. django_cfg/apps/payments/models/subscriptions.py +2 -2
  38. django_cfg/apps/payments/services/__init__.py +64 -7
  39. django_cfg/apps/payments/services/billing/__init__.py +8 -0
  40. django_cfg/apps/payments/services/cache/__init__.py +15 -0
  41. django_cfg/apps/payments/services/cache/base.py +30 -0
  42. django_cfg/apps/payments/services/cache/simple_cache.py +135 -0
  43. django_cfg/apps/payments/services/core/__init__.py +17 -0
  44. django_cfg/apps/payments/services/core/balance_service.py +447 -0
  45. django_cfg/apps/payments/services/core/fallback_service.py +432 -0
  46. django_cfg/apps/payments/services/core/payment_service.py +576 -0
  47. django_cfg/apps/payments/services/core/subscription_service.py +614 -0
  48. django_cfg/apps/payments/services/internal_types.py +297 -0
  49. django_cfg/apps/payments/services/middleware/__init__.py +8 -0
  50. django_cfg/apps/payments/services/monitoring/__init__.py +22 -0
  51. django_cfg/apps/payments/services/monitoring/api_schemas.py +222 -0
  52. django_cfg/apps/payments/services/monitoring/provider_health.py +372 -0
  53. django_cfg/apps/payments/services/providers/__init__.py +22 -0
  54. django_cfg/apps/payments/services/providers/base.py +137 -0
  55. django_cfg/apps/payments/services/providers/cryptapi.py +273 -0
  56. django_cfg/apps/payments/services/providers/cryptomus.py +310 -0
  57. django_cfg/apps/payments/services/providers/nowpayments.py +293 -0
  58. django_cfg/apps/payments/services/providers/registry.py +103 -0
  59. django_cfg/apps/payments/services/security/__init__.py +34 -0
  60. django_cfg/apps/payments/services/security/error_handler.py +637 -0
  61. django_cfg/apps/payments/services/security/payment_notifications.py +342 -0
  62. django_cfg/apps/payments/services/security/webhook_validator.py +475 -0
  63. django_cfg/apps/payments/services/validators/__init__.py +8 -0
  64. django_cfg/apps/payments/signals/__init__.py +13 -0
  65. django_cfg/apps/payments/signals/api_key_signals.py +160 -0
  66. django_cfg/apps/payments/signals/payment_signals.py +128 -0
  67. django_cfg/apps/payments/signals/subscription_signals.py +196 -0
  68. django_cfg/apps/payments/tasks/__init__.py +12 -0
  69. django_cfg/apps/payments/tasks/webhook_processing.py +177 -0
  70. django_cfg/apps/payments/urls.py +5 -5
  71. django_cfg/apps/payments/utils/__init__.py +45 -0
  72. django_cfg/apps/payments/utils/billing_utils.py +342 -0
  73. django_cfg/apps/payments/utils/config_utils.py +245 -0
  74. django_cfg/apps/payments/utils/middleware_utils.py +228 -0
  75. django_cfg/apps/payments/utils/validation_utils.py +94 -0
  76. django_cfg/apps/payments/views/payment_views.py +40 -2
  77. django_cfg/apps/payments/views/webhook_views.py +266 -0
  78. django_cfg/apps/payments/viewsets.py +65 -0
  79. django_cfg/apps/support/signals.py +16 -4
  80. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  81. django_cfg/cli/README.md +2 -2
  82. django_cfg/cli/commands/create_project.py +1 -1
  83. django_cfg/cli/commands/info.py +1 -1
  84. django_cfg/cli/main.py +1 -1
  85. django_cfg/cli/utils.py +5 -5
  86. django_cfg/core/config.py +18 -4
  87. django_cfg/models/payments.py +546 -0
  88. django_cfg/models/revolution.py +1 -1
  89. django_cfg/models/tasks.py +51 -2
  90. django_cfg/modules/base.py +12 -6
  91. django_cfg/modules/django_currency/README.md +104 -269
  92. django_cfg/modules/django_currency/__init__.py +99 -41
  93. django_cfg/modules/django_currency/clients/__init__.py +11 -0
  94. django_cfg/modules/django_currency/clients/coingecko_client.py +257 -0
  95. django_cfg/modules/django_currency/clients/yfinance_client.py +246 -0
  96. django_cfg/modules/django_currency/core/__init__.py +42 -0
  97. django_cfg/modules/django_currency/core/converter.py +169 -0
  98. django_cfg/modules/django_currency/core/exceptions.py +28 -0
  99. django_cfg/modules/django_currency/core/models.py +54 -0
  100. django_cfg/modules/django_currency/database/__init__.py +25 -0
  101. django_cfg/modules/django_currency/database/database_loader.py +507 -0
  102. django_cfg/modules/django_currency/utils/__init__.py +9 -0
  103. django_cfg/modules/django_currency/utils/cache.py +92 -0
  104. django_cfg/modules/django_email.py +42 -4
  105. django_cfg/modules/django_unfold/dashboard.py +20 -0
  106. django_cfg/registry/core.py +10 -0
  107. django_cfg/template_archive/__init__.py +0 -0
  108. django_cfg/template_archive/django_sample.zip +0 -0
  109. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/METADATA +11 -6
  110. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/RECORD +113 -50
  111. django_cfg/apps/agents/examples/__init__.py +0 -3
  112. django_cfg/apps/agents/examples/simple_example.py +0 -161
  113. django_cfg/apps/knowbase/examples/__init__.py +0 -3
  114. django_cfg/apps/knowbase/examples/external_data_usage.py +0 -191
  115. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +0 -199
  116. django_cfg/apps/payments/services/base.py +0 -68
  117. django_cfg/apps/payments/services/nowpayments.py +0 -78
  118. django_cfg/apps/payments/services/providers.py +0 -77
  119. django_cfg/apps/payments/services/redis_service.py +0 -215
  120. django_cfg/modules/django_currency/cache.py +0 -430
  121. django_cfg/modules/django_currency/converter.py +0 -324
  122. django_cfg/modules/django_currency/service.py +0 -277
  123. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/WHEEL +0 -0
  124. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/entry_points.txt +0 -0
  125. {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.print_exc()
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/reformsai/django-cfg
509
+ - **GitHub**: https://github.com/markolofsen/django-cfg
510
510
  - **PyPI**: https://pypi.org/project/django-cfg/
511
- - **Examples**: https://github.com/reformsai/django-cfg/tree/main/examples
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/reformsai/django-cfg](https://github.com/reformsai/django-cfg)
260
+ For more information, visit: [https://github.com/markolofsen/django-cfg](https://github.com/markolofsen/django-cfg)
261
261
 
262
262
  ## 📄 License
263
263
 
@@ -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/reformsai/django-cfg")
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 archive directory
52
- search_paths.append(package_path / "archive" / "django_sample.zip")
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" / "archive" / "django_sample.zip")
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" / "archive" / "django_sample.zip"
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" / "archive" / "django_sample.zip")
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
- enable_payments: bool = Field(
162
- default=False,
163
- description="Enable django-cfg Payments application (universal payment system, subscriptions, API keys, billing)",
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.enable_payments:
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