feat: Add Global Module Settings and Caption to Images
- Introduced GlobalModuleSettings model for platform-wide module enable/disable settings. - Added 'caption' field to Images model to store image captions. - Updated GenerateImagePromptsFunction to handle new caption structure in prompts. - Enhanced AIPromptViewSet to return global prompt types and validate active prompts. - Modified serializers and views to accommodate new caption field and global settings. - Updated frontend components to display captions and filter prompts based on active types. - Created migrations for GlobalModuleSettings and added caption field to Images.
This commit is contained in:
@@ -112,7 +112,7 @@ class GenerateImagePromptsFunction(BaseAIFunction):
|
||||
return prompt
|
||||
|
||||
def parse_response(self, response: str, step_tracker=None) -> Dict:
|
||||
"""Parse AI response - same pattern as other functions"""
|
||||
"""Parse AI response with new structure including captions"""
|
||||
ai_core = AICore(account=getattr(self, 'account', None))
|
||||
json_data = ai_core.extract_json(response)
|
||||
|
||||
@@ -123,9 +123,28 @@ class GenerateImagePromptsFunction(BaseAIFunction):
|
||||
if 'featured_prompt' not in json_data:
|
||||
raise ValueError("Missing 'featured_prompt' in AI response")
|
||||
|
||||
if 'featured_caption' not in json_data:
|
||||
raise ValueError("Missing 'featured_caption' in AI response")
|
||||
|
||||
if 'in_article_prompts' not in json_data:
|
||||
raise ValueError("Missing 'in_article_prompts' in AI response")
|
||||
|
||||
# Validate in_article_prompts structure (should be list of objects with prompt & caption)
|
||||
in_article_prompts = json_data.get('in_article_prompts', [])
|
||||
if in_article_prompts:
|
||||
for idx, item in enumerate(in_article_prompts):
|
||||
if isinstance(item, dict):
|
||||
if 'prompt' not in item:
|
||||
raise ValueError(f"Missing 'prompt' in in_article_prompts[{idx}]")
|
||||
if 'caption' not in item:
|
||||
raise ValueError(f"Missing 'caption' in in_article_prompts[{idx}]")
|
||||
else:
|
||||
# Legacy format (just string) - convert to new format
|
||||
in_article_prompts[idx] = {
|
||||
'prompt': str(item),
|
||||
'caption': '' # Empty caption for legacy data
|
||||
}
|
||||
|
||||
return json_data
|
||||
|
||||
def save_output(
|
||||
@@ -151,23 +170,33 @@ class GenerateImagePromptsFunction(BaseAIFunction):
|
||||
prompts_created = 0
|
||||
|
||||
with transaction.atomic():
|
||||
# Save featured image prompt - use content instead of task
|
||||
# Save featured image prompt with caption
|
||||
Images.objects.update_or_create(
|
||||
content=content,
|
||||
image_type='featured',
|
||||
defaults={
|
||||
'prompt': parsed['featured_prompt'],
|
||||
'caption': parsed.get('featured_caption', ''),
|
||||
'status': 'pending',
|
||||
'position': 0,
|
||||
}
|
||||
)
|
||||
prompts_created += 1
|
||||
|
||||
# Save in-article image prompts
|
||||
# Save in-article image prompts with captions
|
||||
in_article_prompts = parsed.get('in_article_prompts', [])
|
||||
h2_headings = extracted.get('h2_headings', [])
|
||||
|
||||
for idx, prompt_text in enumerate(in_article_prompts[:max_images]):
|
||||
for idx, prompt_data in enumerate(in_article_prompts[:max_images]):
|
||||
# Handle both new format (dict with prompt & caption) and legacy format (string)
|
||||
if isinstance(prompt_data, dict):
|
||||
prompt_text = prompt_data.get('prompt', '')
|
||||
caption_text = prompt_data.get('caption', '')
|
||||
else:
|
||||
# Legacy format - just a string prompt
|
||||
prompt_text = str(prompt_data)
|
||||
caption_text = ''
|
||||
|
||||
heading = h2_headings[idx] if idx < len(h2_headings) else f"Section {idx + 1}"
|
||||
|
||||
Images.objects.update_or_create(
|
||||
@@ -176,6 +205,7 @@ class GenerateImagePromptsFunction(BaseAIFunction):
|
||||
position=idx + 1,
|
||||
defaults={
|
||||
'prompt': prompt_text,
|
||||
'caption': caption_text,
|
||||
'status': 'pending',
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user