Add new fields to TasksSerializer and enhance auto_generate_content_task with detailed step tracking
- Updated TasksSerializer to include 'primary_keyword', 'secondary_keywords', 'tags', and 'categories'. - Enhanced auto_generate_content_task to track progress with detailed steps, including initialization, preparation, AI call, parsing, and saving. - Updated progress modal to reflect new phases and improved animation for smoother user experience. - Adjusted routing and configuration for content and drafts pages in the frontend.
This commit is contained in:
@@ -30,6 +30,10 @@ class TasksSerializer(serializers.ModelSerializer):
|
||||
'word_count',
|
||||
'meta_title',
|
||||
'meta_description',
|
||||
'primary_keyword',
|
||||
'secondary_keywords',
|
||||
'tags',
|
||||
'categories',
|
||||
'assigned_post_id',
|
||||
'post_url',
|
||||
'created_at',
|
||||
|
||||
@@ -3,6 +3,7 @@ Celery tasks for Writer module - AI content generation
|
||||
"""
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
from typing import List
|
||||
from django.db import transaction
|
||||
from igny8_core.modules.writer.models import Tasks, Images, Content
|
||||
@@ -35,7 +36,29 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
account_id: Account ID for account isolation
|
||||
"""
|
||||
try:
|
||||
# Step tracking for progress modal
|
||||
step_counter = 0
|
||||
request_steps = []
|
||||
response_steps = []
|
||||
|
||||
def add_step(step_name, status='success', message='', step_type='request'):
|
||||
nonlocal step_counter
|
||||
step_counter += 1
|
||||
step = {
|
||||
'stepNumber': step_counter,
|
||||
'stepName': step_name,
|
||||
'status': status,
|
||||
'message': message,
|
||||
'timestamp': time.time()
|
||||
}
|
||||
if step_type == 'request':
|
||||
request_steps.append(step)
|
||||
else:
|
||||
response_steps.append(step)
|
||||
return step
|
||||
|
||||
# Initialize progress
|
||||
add_step('INIT', 'success', 'Initializing content generation...', 'request')
|
||||
self.update_state(
|
||||
state='PROGRESS',
|
||||
meta={
|
||||
@@ -43,7 +66,9 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
'total': len(task_ids),
|
||||
'percentage': 0,
|
||||
'message': 'Initializing content generation...',
|
||||
'phase': 'initializing'
|
||||
'phase': 'INIT',
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps
|
||||
}
|
||||
)
|
||||
|
||||
@@ -190,15 +215,18 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
|
||||
total_tasks = len(tasks)
|
||||
|
||||
# Update progress: Preparing tasks (0-5%)
|
||||
# Update progress: Preparing tasks
|
||||
add_step('PREP', 'success', f'Preparing {total_tasks} tasks for content generation...', 'request')
|
||||
self.update_state(
|
||||
state='PROGRESS',
|
||||
meta={
|
||||
'current': 0,
|
||||
'total': total_tasks,
|
||||
'percentage': 2,
|
||||
'percentage': 10,
|
||||
'message': f'Preparing {total_tasks} tasks for content generation...',
|
||||
'phase': 'preparing'
|
||||
'phase': 'PREP',
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps
|
||||
}
|
||||
)
|
||||
|
||||
@@ -286,17 +314,21 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
logger.warning(f" - Task idea_id: {task.idea_id}")
|
||||
# Don't skip - idea is nullable
|
||||
|
||||
# Update progress: Processing task (5-90%)
|
||||
progress_pct = 5 + int((idx / total_tasks) * 85)
|
||||
# Update progress: Processing task
|
||||
# Calculate base percentage: 10% (PREP) + progress through tasks (10-50%)
|
||||
base_pct = 10
|
||||
task_progress_pct = base_pct + int((idx / total_tasks) * 40) # 10-50% for task prep
|
||||
self.update_state(
|
||||
state='PROGRESS',
|
||||
meta={
|
||||
'current': idx + 1,
|
||||
'total': total_tasks,
|
||||
'percentage': progress_pct,
|
||||
'message': f"Generating content for '{task.title}' ({idx + 1} of {total_tasks})...",
|
||||
'phase': 'generating',
|
||||
'current_item': task.title
|
||||
'percentage': task_progress_pct,
|
||||
'message': f"Preparing content generation for '{task.title}' ({idx + 1} of {total_tasks})...",
|
||||
'phase': 'PREP',
|
||||
'current_item': task.title,
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps
|
||||
}
|
||||
)
|
||||
|
||||
@@ -496,15 +528,19 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
logger.info("=" * 80)
|
||||
|
||||
# Update progress: Generating with AI
|
||||
add_step('AI_CALL', 'success', f"Generating article content for '{task.title}'...", 'request')
|
||||
ai_call_pct = 50 + int((idx / total_tasks) * 20) # 50-70% for AI call
|
||||
self.update_state(
|
||||
state='PROGRESS',
|
||||
meta={
|
||||
'current': idx + 1,
|
||||
'total': total_tasks,
|
||||
'percentage': progress_pct,
|
||||
'percentage': ai_call_pct,
|
||||
'message': f"Generating article content for '{task.title}'...",
|
||||
'phase': 'generating',
|
||||
'current_item': task.title
|
||||
'phase': 'AI_CALL',
|
||||
'current_item': task.title,
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps
|
||||
}
|
||||
)
|
||||
|
||||
@@ -579,6 +615,23 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
logger.info(f" * Cost: ${result.get('cost', 'N/A')}")
|
||||
logger.info(f" * Raw content preview (first 200 chars): {content[:200]}...")
|
||||
|
||||
# Update progress: Parsing content
|
||||
add_step('PARSE', 'success', f"Processing content for '{task.title}'...", 'response')
|
||||
parse_pct = 70 + int((idx / total_tasks) * 10) # 70-80% for parsing
|
||||
self.update_state(
|
||||
state='PROGRESS',
|
||||
meta={
|
||||
'current': idx + 1,
|
||||
'total': total_tasks,
|
||||
'percentage': parse_pct,
|
||||
'message': f"Processing content for '{task.title}'...",
|
||||
'phase': 'PARSE',
|
||||
'current_item': task.title,
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps
|
||||
}
|
||||
)
|
||||
|
||||
# Normalize content from different AI response formats
|
||||
logger.info(f" * Normalizing content (length: {len(content)} chars)...")
|
||||
try:
|
||||
@@ -616,15 +669,19 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
logger.info(f" * ✓ Word count calculated: {word_count} words (from normalized HTML)")
|
||||
|
||||
# Update progress: Saving content
|
||||
add_step('SAVE', 'success', f"Saving content for '{task.title}' ({word_count} words)...", 'request')
|
||||
save_pct = 85 + int((idx / total_tasks) * 10) # 85-95% for saving
|
||||
self.update_state(
|
||||
state='PROGRESS',
|
||||
meta={
|
||||
'current': idx + 1,
|
||||
'total': total_tasks,
|
||||
'percentage': progress_pct,
|
||||
'percentage': save_pct,
|
||||
'message': f"Saving content for '{task.title}' ({word_count} words)...",
|
||||
'phase': 'saving',
|
||||
'current_item': task.title
|
||||
'phase': 'SAVE',
|
||||
'current_item': task.title,
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps
|
||||
}
|
||||
)
|
||||
|
||||
@@ -668,6 +725,9 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
task.save()
|
||||
logger.info(f" * ✓ Task saved successfully to database")
|
||||
|
||||
# Mark save step as complete
|
||||
add_step('SAVE', 'success', f"Content saved for '{task.title}'", 'response')
|
||||
|
||||
tasks_updated += 1
|
||||
logger.info(f" * ✓ Task {task.id} content generation completed successfully")
|
||||
|
||||
@@ -687,8 +747,9 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
logger.info(f"✓ TASK {task.id} PROCESSING COMPLETE")
|
||||
logger.info("=" * 80)
|
||||
|
||||
# Final progress update
|
||||
# Final progress update - mark as DONE
|
||||
final_message = f"Content generation complete: {tasks_updated} articles generated"
|
||||
add_step('DONE', 'success', final_message, 'response')
|
||||
logger.info("=" * 80)
|
||||
logger.info(f"TASK COMPLETION SUMMARY")
|
||||
logger.info(f" - Total tasks processed: {total_tasks}")
|
||||
@@ -696,6 +757,21 @@ def auto_generate_content_task(self, task_ids: List[int], account_id: int = None
|
||||
logger.info(f" - Tasks failed/skipped: {total_tasks - tasks_updated}")
|
||||
logger.info("=" * 80)
|
||||
|
||||
# Update final state before returning
|
||||
self.update_state(
|
||||
state='SUCCESS',
|
||||
meta={
|
||||
'current': total_tasks,
|
||||
'total': total_tasks,
|
||||
'percentage': 100,
|
||||
'message': final_message,
|
||||
'phase': 'DONE',
|
||||
'request_steps': request_steps,
|
||||
'response_steps': response_steps,
|
||||
'tasks_updated': tasks_updated
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'tasks_updated': tasks_updated,
|
||||
|
||||
Reference in New Issue
Block a user