Refactor content handling in GenerateContentFunction and update related models and serializers

- Enhanced GenerateContentFunction to save content in a dedicated Content model, separating it from the Tasks model.
- Updated Tasks model to remove SEO-related fields, now managed in the Content model.
- Modified TasksSerializer to include new content fields and adjusted the API to reflect these changes.
- Improved the auto_generate_content_task method to utilize the new save_output method for better content management.
- Updated frontend components to display new content structure and metadata effectively.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-10 14:06:15 +00:00
parent 8bb4c5d016
commit 8b6e18649c
11 changed files with 596 additions and 356 deletions

View File

@@ -7,7 +7,7 @@ import re
from typing import Dict, List, Any
from django.db import transaction
from igny8_core.ai.base import BaseAIFunction
from igny8_core.modules.writer.models import Tasks
from igny8_core.modules.writer.models import Tasks, Content as TaskContent
from igny8_core.ai.ai_core import AICore
from igny8_core.ai.validators import validate_tasks_exist
from igny8_core.ai.prompts import PromptRegistry
@@ -188,69 +188,111 @@ class GenerateContentFunction(BaseAIFunction):
# Handle parsed response - can be dict (JSON) or string (plain text)
if isinstance(parsed, dict):
# JSON response with structured fields
content = parsed.get('content', '')
title = parsed.get('title', task.title)
meta_title = parsed.get('meta_title', title or task.title)
content_html = parsed.get('content', '')
title = parsed.get('title') or task.title
meta_title = parsed.get('meta_title') or title or task.title
meta_description = parsed.get('meta_description', '')
word_count = parsed.get('word_count', 0)
primary_keyword = parsed.get('primary_keyword', '')
secondary_keywords = parsed.get('secondary_keywords', [])
tags = parsed.get('tags', [])
categories = parsed.get('categories', [])
content_status = parsed.get('status', 'draft')
else:
# Plain text response (legacy)
content = str(parsed)
content_html = str(parsed)
title = task.title
meta_title = task.title
meta_description = (task.description or '')[:160] if task.description else ''
meta_title = task.meta_title or task.title
meta_description = task.meta_description or (task.description or '')[:160] if task.description else ''
word_count = 0
primary_keyword = ''
secondary_keywords = []
tags = []
categories = []
content_status = 'draft'
# Calculate word count if not provided
if not word_count and content:
text_for_counting = re.sub(r'<[^>]+>', '', content)
if not word_count and content_html:
text_for_counting = re.sub(r'<[^>]+>', '', content_html)
word_count = len(text_for_counting.split())
# Update task with all fields
if content:
task.content = content
if title and title != task.title:
task.title = title
task.word_count = word_count
# SEO fields
if meta_title:
task.meta_title = meta_title
elif not task.meta_title:
task.meta_title = task.title # Fallback to title
if meta_description:
task.meta_description = meta_description
elif not task.meta_description and task.description:
task.meta_description = (task.description or '')[:160] # Fallback to description
if primary_keyword:
task.primary_keyword = primary_keyword
if secondary_keywords:
task.secondary_keywords = secondary_keywords if isinstance(secondary_keywords, list) else []
if tags:
task.tags = tags if isinstance(tags, list) else []
if categories:
task.categories = categories if isinstance(categories, list) else []
task.status = 'draft'
task.save()
# Ensure related content record exists
content_record, _created = TaskContent.objects.get_or_create(
task=task,
defaults={
'account': task.account,
'site': task.site,
'sector': task.sector,
'html_content': content_html or '',
'word_count': word_count or 0,
'status': 'draft',
},
)
# Update content fields
if content_html:
content_record.html_content = content_html
content_record.word_count = word_count or content_record.word_count or 0
content_record.title = title
content_record.meta_title = meta_title
content_record.meta_description = meta_description
content_record.primary_keyword = primary_keyword or ''
if isinstance(secondary_keywords, list):
content_record.secondary_keywords = secondary_keywords
elif secondary_keywords:
content_record.secondary_keywords = [secondary_keywords]
else:
content_record.secondary_keywords = []
if isinstance(tags, list):
content_record.tags = tags
elif tags:
content_record.tags = [tags]
else:
content_record.tags = []
if isinstance(categories, list):
content_record.categories = categories
elif categories:
content_record.categories = [categories]
else:
content_record.categories = []
content_record.status = content_status or 'draft'
# Merge any extra fields into metadata (non-standard keys)
if isinstance(parsed, dict):
excluded_keys = {
'content',
'title',
'meta_title',
'meta_description',
'primary_keyword',
'secondary_keywords',
'tags',
'categories',
'word_count',
'status',
}
extra_meta = {k: v for k, v in parsed.items() if k not in excluded_keys}
existing_meta = content_record.metadata or {}
existing_meta.update(extra_meta)
content_record.metadata = existing_meta
# Align foreign keys to ensure consistency
content_record.account = task.account
content_record.site = task.site
content_record.sector = task.sector
content_record.task = task
content_record.save()
# Update task status - keep task data intact but mark as completed
task.status = 'completed'
task.save(update_fields=['status', 'updated_at'])
return {
'count': 1,
'tasks_updated': 1,
'word_count': word_count
'word_count': content_record.word_count,
}