SEction 9-10

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-01 08:10:24 +00:00
parent 0340016932
commit 41e124d8e8
11 changed files with 2180 additions and 0 deletions

View File

@@ -0,0 +1,255 @@
"""
Defaults Service
Creates sites with default settings for simplified onboarding.
"""
import logging
from typing import Dict, Any, Tuple, Optional
from django.db import transaction
from django.utils import timezone
from igny8_core.auth.models import Account, Site
from igny8_core.business.integration.models import PublishingSettings
from igny8_core.business.automation.models import AutomationConfig
logger = logging.getLogger(__name__)
# Default settings for new sites
DEFAULT_PUBLISHING_SETTINGS = {
'auto_approval_enabled': True,
'auto_publish_enabled': True,
'daily_publish_limit': 3,
'weekly_publish_limit': 15,
'monthly_publish_limit': 50,
'publish_days': ['mon', 'tue', 'wed', 'thu', 'fri'],
'publish_time_slots': ['09:00', '14:00', '18:00'],
}
DEFAULT_AUTOMATION_SETTINGS = {
'is_enabled': True,
'frequency': 'daily',
'scheduled_time': '02:00',
'stage_1_batch_size': 50,
'stage_2_batch_size': 1,
'stage_3_batch_size': 20,
'stage_4_batch_size': 1,
'stage_5_batch_size': 1,
'stage_6_batch_size': 1,
'within_stage_delay': 3,
'between_stage_delay': 5,
}
class DefaultsService:
"""
Service for creating sites with sensible defaults.
Used during onboarding for a simplified first-run experience.
"""
def __init__(self, account: Account):
self.account = account
@transaction.atomic
def create_site_with_defaults(
self,
site_data: Dict[str, Any],
publishing_overrides: Optional[Dict[str, Any]] = None,
automation_overrides: Optional[Dict[str, Any]] = None,
) -> Tuple[Site, PublishingSettings, AutomationConfig]:
"""
Create a new site with default publishing and automation settings.
Args:
site_data: Dict with site fields (name, domain, etc.)
publishing_overrides: Optional overrides for publishing settings
automation_overrides: Optional overrides for automation settings
Returns:
Tuple of (Site, PublishingSettings, AutomationConfig)
"""
# Create the site
site = Site.objects.create(
account=self.account,
name=site_data.get('name', 'My Site'),
domain=site_data.get('domain', ''),
base_url=site_data.get('base_url', ''),
hosting_type=site_data.get('hosting_type', 'wordpress'),
is_active=site_data.get('is_active', True),
)
logger.info(f"Created site: {site.name} (id={site.id}) for account {self.account.id}")
# Create publishing settings with defaults
publishing_settings = self._create_publishing_settings(
site,
overrides=publishing_overrides
)
# Create automation config with defaults
automation_config = self._create_automation_config(
site,
overrides=automation_overrides
)
return site, publishing_settings, automation_config
def _create_publishing_settings(
self,
site: Site,
overrides: Optional[Dict[str, Any]] = None
) -> PublishingSettings:
"""Create publishing settings with defaults, applying any overrides."""
settings_data = {**DEFAULT_PUBLISHING_SETTINGS}
if overrides:
settings_data.update(overrides)
publishing_settings = PublishingSettings.objects.create(
account=self.account,
site=site,
**settings_data
)
logger.info(
f"Created publishing settings for site {site.id}: "
f"auto_approval={publishing_settings.auto_approval_enabled}, "
f"auto_publish={publishing_settings.auto_publish_enabled}"
)
return publishing_settings
def _create_automation_config(
self,
site: Site,
overrides: Optional[Dict[str, Any]] = None
) -> AutomationConfig:
"""Create automation config with defaults, applying any overrides."""
config_data = {**DEFAULT_AUTOMATION_SETTINGS}
if overrides:
config_data.update(overrides)
# Calculate next run time (tomorrow at scheduled time)
scheduled_time = config_data.pop('scheduled_time', '02:00')
automation_config = AutomationConfig.objects.create(
account=self.account,
site=site,
scheduled_time=scheduled_time,
**config_data
)
# Set next run to tomorrow at scheduled time if enabled
if automation_config.is_enabled:
next_run = self._calculate_initial_next_run(scheduled_time)
automation_config.next_run_at = next_run
automation_config.save(update_fields=['next_run_at'])
logger.info(
f"Created automation config for site {site.id}: "
f"enabled={automation_config.is_enabled}, "
f"frequency={automation_config.frequency}, "
f"next_run={automation_config.next_run_at}"
)
return automation_config
def _calculate_initial_next_run(self, scheduled_time: str) -> timezone.datetime:
"""Calculate the initial next run datetime (tomorrow at scheduled time)."""
now = timezone.now()
# Parse time
try:
hour, minute = map(int, scheduled_time.split(':'))
except (ValueError, AttributeError):
hour, minute = 2, 0 # Default to 2:00 AM
# Set to tomorrow at the scheduled time
next_run = now.replace(
hour=hour,
minute=minute,
second=0,
microsecond=0
)
# If the time has passed today, schedule for tomorrow
if next_run <= now:
next_run += timezone.timedelta(days=1)
return next_run
@transaction.atomic
def apply_defaults_to_existing_site(
self,
site: Site,
force_overwrite: bool = False
) -> Tuple[PublishingSettings, AutomationConfig]:
"""
Apply default settings to an existing site.
Args:
site: Existing Site instance
force_overwrite: If True, overwrite existing settings. If False, only create if missing.
Returns:
Tuple of (PublishingSettings, AutomationConfig)
"""
# Handle publishing settings
if force_overwrite:
PublishingSettings.objects.filter(site=site).delete()
publishing_settings = self._create_publishing_settings(site)
else:
publishing_settings, created = PublishingSettings.objects.get_or_create(
site=site,
defaults={
'account': self.account,
**DEFAULT_PUBLISHING_SETTINGS
}
)
if not created:
logger.info(f"Publishing settings already exist for site {site.id}")
# Handle automation config
if force_overwrite:
AutomationConfig.objects.filter(site=site).delete()
automation_config = self._create_automation_config(site)
else:
try:
automation_config = AutomationConfig.objects.get(site=site)
logger.info(f"Automation config already exists for site {site.id}")
except AutomationConfig.DoesNotExist:
automation_config = self._create_automation_config(site)
return publishing_settings, automation_config
def create_site_with_defaults(
account: Account,
site_data: Dict[str, Any],
publishing_overrides: Optional[Dict[str, Any]] = None,
automation_overrides: Optional[Dict[str, Any]] = None,
) -> Tuple[Site, PublishingSettings, AutomationConfig]:
"""
Convenience function to create a site with default settings.
This is the main entry point for the onboarding flow.
Usage:
from igny8_core.business.integration.services.defaults_service import create_site_with_defaults
site, pub_settings, auto_config = create_site_with_defaults(
account=request.user.account,
site_data={
'name': 'My Blog',
'domain': 'myblog.com',
'hosting_type': 'wordpress',
}
)
"""
service = DefaultsService(account)
return service.create_site_with_defaults(
site_data,
publishing_overrides=publishing_overrides,
automation_overrides=automation_overrides,
)