image gen mess
This commit is contained in:
@@ -403,7 +403,7 @@ class GlobalIntegrationSettingsAdmin(Igny8ModelAdmin):
|
||||
"description": "Global Runware image generation configuration"
|
||||
}),
|
||||
("Universal Image Settings", {
|
||||
"fields": ("image_quality", "image_style", "max_in_article_images", "desktop_image_size", "mobile_image_size"),
|
||||
"fields": ("image_quality", "image_style", "max_in_article_images", "desktop_image_size"),
|
||||
"description": "Image quality, style, and sizing settings that apply to ALL providers (DALL-E, Runware, etc.)"
|
||||
}),
|
||||
("Status", {
|
||||
|
||||
@@ -198,14 +198,28 @@ class GlobalIntegrationSettings(models.Model):
|
||||
('hd', 'HD'),
|
||||
]
|
||||
|
||||
IMAGE_STYLE_CHOICES = [
|
||||
('vivid', 'Vivid'),
|
||||
('natural', 'Natural'),
|
||||
('realistic', 'Realistic'),
|
||||
('artistic', 'Artistic'),
|
||||
('cartoon', 'Cartoon'),
|
||||
# Image style choices with descriptions - used by both Runware and OpenAI
|
||||
# Format: (value, label, description)
|
||||
IMAGE_STYLE_OPTIONS = [
|
||||
('photorealistic', 'Photorealistic', 'Ultra realistic photography style, natural lighting, real world look'),
|
||||
('illustration', 'Illustration', 'Digital illustration, clean lines, artistic but not realistic'),
|
||||
('3d_render', '3D Render', 'Computer generated 3D style, modern, polished, depth and lighting'),
|
||||
('minimal_flat', 'Minimal / Flat Design', 'Simple shapes, flat colors, modern UI and graphic design look'),
|
||||
('artistic', 'Artistic / Painterly', 'Expressive, painted or hand drawn aesthetic'),
|
||||
('cartoon', 'Cartoon / Stylized', 'Playful, exaggerated forms, animated or mascot style'),
|
||||
]
|
||||
|
||||
# Choices for Django model field (value, label only)
|
||||
IMAGE_STYLE_CHOICES = [(opt[0], opt[1]) for opt in IMAGE_STYLE_OPTIONS]
|
||||
|
||||
# OpenAI DALL-E specific styles with descriptions (subset)
|
||||
DALLE_STYLE_OPTIONS = [
|
||||
('natural', 'Natural', 'More realistic, photographic style'),
|
||||
('vivid', 'Vivid', 'Hyper-real, dramatic, artistic'),
|
||||
]
|
||||
|
||||
DALLE_STYLE_CHOICES = [(opt[0], opt[1]) for opt in DALLE_STYLE_OPTIONS]
|
||||
|
||||
IMAGE_SERVICE_CHOICES = [
|
||||
('openai', 'OpenAI DALL-E'),
|
||||
('runware', 'Runware'),
|
||||
@@ -335,8 +349,8 @@ class GlobalIntegrationSettings(models.Model):
|
||||
help_text="Default image quality for all providers (accounts can override if plan allows)"
|
||||
)
|
||||
image_style = models.CharField(
|
||||
max_length=20,
|
||||
default='realistic',
|
||||
max_length=30,
|
||||
default='photorealistic',
|
||||
choices=IMAGE_STYLE_CHOICES,
|
||||
help_text="Default image style for all providers (accounts can override if plan allows)"
|
||||
)
|
||||
|
||||
@@ -723,7 +723,7 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
|
||||
# Universal image settings (applies to all providers)
|
||||
for key in ['image_type', 'image_quality', 'image_style', 'max_in_article_images', 'image_format',
|
||||
'desktop_enabled', 'mobile_enabled', 'featured_image_size', 'desktop_image_size']:
|
||||
'desktop_enabled', 'featured_image_size', 'desktop_image_size']:
|
||||
if key in config:
|
||||
clean_config[key] = config[key]
|
||||
|
||||
@@ -844,9 +844,17 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
}
|
||||
|
||||
elif integration_type == 'image_generation':
|
||||
# Model-specific landscape sizes
|
||||
MODEL_LANDSCAPE_SIZES = {
|
||||
'runware:97@1': '1280x768',
|
||||
'bria:10@1': '1344x768',
|
||||
'google:4@2': '1376x768',
|
||||
}
|
||||
|
||||
# Get default service and model based on global settings
|
||||
default_service = global_settings.default_image_service
|
||||
default_model = global_settings.dalle_model if default_service == 'openai' else global_settings.runware_model
|
||||
model_landscape_size = MODEL_LANDSCAPE_SIZES.get(default_model, '1280x768')
|
||||
|
||||
response_data = {
|
||||
'id': 'image_generation',
|
||||
@@ -862,10 +870,8 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
'max_in_article_images': global_settings.max_in_article_images,
|
||||
'image_format': 'webp',
|
||||
'desktop_enabled': True,
|
||||
'mobile_enabled': True,
|
||||
'featured_image_size': global_settings.dalle_size,
|
||||
'featured_image_size': model_landscape_size, # Model-specific landscape
|
||||
'desktop_image_size': global_settings.desktop_image_size,
|
||||
'mobile_image_size': global_settings.mobile_image_size,
|
||||
'using_global': True,
|
||||
}
|
||||
|
||||
@@ -897,7 +903,7 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
response_data['runwareModel'] = config['runwareModel']
|
||||
# Universal image settings
|
||||
for key in ['image_type', 'image_quality', 'image_style', 'max_in_article_images', 'image_format',
|
||||
'desktop_enabled', 'mobile_enabled', 'featured_image_size', 'desktop_image_size']:
|
||||
'desktop_enabled', 'featured_image_size', 'desktop_image_size']:
|
||||
if key in config:
|
||||
response_data[key] = config[key]
|
||||
except IntegrationSettings.DoesNotExist:
|
||||
@@ -923,9 +929,18 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
|
||||
@action(detail=False, methods=['get'], url_path='image_generation', url_name='image_generation_settings')
|
||||
def get_image_generation_settings(self, request):
|
||||
"""Get image generation settings for current account
|
||||
Normal users fallback to system account (aws-admin) settings
|
||||
"""Get image generation settings for current account.
|
||||
|
||||
Architecture:
|
||||
1. If account has IntegrationSettings override -> use it (with GlobalIntegrationSettings as fallback for missing fields)
|
||||
2. Otherwise -> use GlobalIntegrationSettings (platform-wide defaults)
|
||||
|
||||
Note: API keys are ALWAYS from GlobalIntegrationSettings (accounts cannot override API keys).
|
||||
Account IntegrationSettings only store model/parameter overrides.
|
||||
"""
|
||||
from .models import IntegrationSettings
|
||||
from .global_settings_models import GlobalIntegrationSettings
|
||||
|
||||
account = getattr(request, 'account', None)
|
||||
|
||||
if not account:
|
||||
@@ -933,89 +948,90 @@ class IntegrationSettingsViewSet(viewsets.ViewSet):
|
||||
user = getattr(request, 'user', None)
|
||||
if user and hasattr(user, 'is_authenticated') and user.is_authenticated:
|
||||
account = getattr(user, 'account', None)
|
||||
# Fallback to default account
|
||||
if not account:
|
||||
from igny8_core.auth.models import Account
|
||||
try:
|
||||
account = Account.objects.first()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not account:
|
||||
return error_response(
|
||||
error='Account not found',
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
request=request
|
||||
)
|
||||
# Get GlobalIntegrationSettings (platform defaults - always available)
|
||||
global_settings = GlobalIntegrationSettings.get_instance()
|
||||
|
||||
# Model-specific landscape sizes (from GlobalIntegrationSettings)
|
||||
MODEL_LANDSCAPE_SIZES = {
|
||||
'runware:97@1': '1280x768', # Hi Dream Full landscape
|
||||
'bria:10@1': '1344x768', # Bria 3.2 landscape (16:9)
|
||||
'google:4@2': '1376x768', # Nano Banana landscape (16:9)
|
||||
'dall-e-3': '1792x1024', # DALL-E 3 landscape
|
||||
'dall-e-2': '1024x1024', # DALL-E 2 square only
|
||||
}
|
||||
|
||||
try:
|
||||
from .models import IntegrationSettings
|
||||
from igny8_core.auth.models import Account
|
||||
|
||||
# Try to get settings for user's account first
|
||||
try:
|
||||
integration = IntegrationSettings.objects.get(
|
||||
account=account,
|
||||
integration_type='image_generation',
|
||||
is_active=True
|
||||
)
|
||||
logger.info(f"[get_image_generation_settings] Found settings for account {account.id}")
|
||||
except IntegrationSettings.DoesNotExist:
|
||||
# Fallback to system account (aws-admin) settings - normal users use centralized settings
|
||||
logger.info(f"[get_image_generation_settings] No settings for account {account.id}, falling back to system account")
|
||||
# Check if account has specific overrides
|
||||
account_config = {}
|
||||
if account:
|
||||
try:
|
||||
system_account = Account.objects.get(slug='aws-admin')
|
||||
integration = IntegrationSettings.objects.get(
|
||||
account=system_account,
|
||||
account=account,
|
||||
integration_type='image_generation',
|
||||
is_active=True
|
||||
)
|
||||
logger.info(f"[get_image_generation_settings] Using system account (aws-admin) settings")
|
||||
except (Account.DoesNotExist, IntegrationSettings.DoesNotExist):
|
||||
logger.error("[get_image_generation_settings] No image generation settings found in aws-admin account")
|
||||
return error_response(
|
||||
error='Image generation settings not configured in aws-admin account',
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
request=request
|
||||
)
|
||||
account_config = integration.config or {}
|
||||
logger.info(f"[get_image_generation_settings] Found account {account.id} override: {list(account_config.keys())}")
|
||||
except IntegrationSettings.DoesNotExist:
|
||||
logger.info(f"[get_image_generation_settings] No override for account {account.id if account else 'None'}, using GlobalIntegrationSettings")
|
||||
|
||||
config = integration.config or {}
|
||||
# Build response using account overrides with global fallbacks
|
||||
provider = account_config.get('provider') or global_settings.default_image_service
|
||||
|
||||
# Debug: Log what's actually in the config
|
||||
logger.info(f"[get_image_generation_settings] Full config: {config}")
|
||||
logger.info(f"[get_image_generation_settings] Config keys: {list(config.keys())}")
|
||||
logger.info(f"[get_image_generation_settings] model field: {config.get('model')}")
|
||||
logger.info(f"[get_image_generation_settings] imageModel field: {config.get('imageModel')}")
|
||||
# Get model based on provider
|
||||
if provider == 'runware':
|
||||
model = account_config.get('model') or account_config.get('imageModel') or global_settings.runware_model
|
||||
else:
|
||||
model = account_config.get('model') or account_config.get('imageModel') or global_settings.dalle_model
|
||||
|
||||
# Get model - try 'model' first, then 'imageModel' as fallback
|
||||
model = config.get('model') or config.get('imageModel') or 'dall-e-3'
|
||||
# Get model-specific landscape size
|
||||
model_landscape_size = MODEL_LANDSCAPE_SIZES.get(model, '1280x768')
|
||||
default_featured_size = model_landscape_size if provider == 'runware' else '1792x1024'
|
||||
|
||||
# Set defaults for image sizes if not present
|
||||
provider = config.get('provider', 'openai')
|
||||
default_featured_size = '1280x832' if provider == 'runware' else '1024x1024'
|
||||
# Get image style with provider-specific defaults
|
||||
image_style = account_config.get('image_type') or global_settings.image_style
|
||||
|
||||
# Style options from GlobalIntegrationSettings model - loaded dynamically
|
||||
# Runware: Uses all styles with prompt enhancement
|
||||
# OpenAI DALL-E: Only supports 'natural' or 'vivid'
|
||||
if provider == 'openai':
|
||||
# Get DALL-E styles from model definition
|
||||
available_styles = [
|
||||
{'value': opt[0], 'label': opt[1], 'description': opt[2]}
|
||||
for opt in GlobalIntegrationSettings.DALLE_STYLE_OPTIONS
|
||||
]
|
||||
# Map stored style to DALL-E compatible
|
||||
if image_style not in ['vivid', 'natural']:
|
||||
image_style = 'natural' # Default to natural for photorealistic
|
||||
else:
|
||||
# Get Runware styles from model definition
|
||||
available_styles = [
|
||||
{'value': opt[0], 'label': opt[1], 'description': opt[2]}
|
||||
for opt in GlobalIntegrationSettings.IMAGE_STYLE_OPTIONS
|
||||
]
|
||||
# Default to photorealistic for Runware if not set
|
||||
if not image_style or image_style in ['natural', 'vivid']:
|
||||
image_style = 'photorealistic'
|
||||
|
||||
logger.info(f"[get_image_generation_settings] Returning: provider={provider}, model={model}, image_style={image_style}")
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
'config': {
|
||||
'provider': config.get('provider', 'openai'),
|
||||
'provider': provider,
|
||||
'model': model,
|
||||
'image_type': config.get('image_type', 'realistic'),
|
||||
'max_in_article_images': config.get('max_in_article_images'),
|
||||
'image_format': config.get('image_format', 'webp'),
|
||||
'desktop_enabled': config.get('desktop_enabled', True),
|
||||
'mobile_enabled': config.get('mobile_enabled', True),
|
||||
'featured_image_size': config.get('featured_image_size', default_featured_size),
|
||||
'desktop_image_size': config.get('desktop_image_size', '1024x1024'),
|
||||
'image_type': image_style,
|
||||
'available_styles': available_styles, # Loaded from GlobalIntegrationSettings model
|
||||
'max_in_article_images': account_config.get('max_in_article_images') or global_settings.max_in_article_images,
|
||||
'image_format': account_config.get('image_format', 'webp'),
|
||||
'desktop_enabled': account_config.get('desktop_enabled', True),
|
||||
'featured_image_size': account_config.get('featured_image_size') or default_featured_size,
|
||||
'desktop_image_size': account_config.get('desktop_image_size') or global_settings.desktop_image_size,
|
||||
}
|
||||
},
|
||||
request=request
|
||||
)
|
||||
except IntegrationSettings.DoesNotExist:
|
||||
return error_response(
|
||||
error='Image generation settings not configured',
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
request=request
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"[get_image_generation_settings] Error: {str(e)}", exc_info=True)
|
||||
return error_response(
|
||||
|
||||
Reference in New Issue
Block a user