SEction 9-10
This commit is contained in:
@@ -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,
|
||||
)
|
||||
Reference in New Issue
Block a user