fine tuning

This commit is contained in:
IGNY8 VPS (Salman)
2025-11-28 12:25:45 +00:00
parent 831b179c49
commit 0839455418
15 changed files with 840 additions and 95 deletions

View File

@@ -161,6 +161,7 @@ class GenerateContentFunction(BaseAIFunction):
"""
STAGE 3: Save content using final Stage 1 Content model schema.
Creates independent Content record (no OneToOne to Task).
Handles tags and categories from AI response.
"""
if isinstance(original_data, list):
task = original_data[0] if original_data else None
@@ -179,6 +180,9 @@ class GenerateContentFunction(BaseAIFunction):
meta_description = parsed.get('meta_description') or parsed.get('seo_description')
primary_keyword = parsed.get('primary_keyword') or parsed.get('focus_keyword')
secondary_keywords = parsed.get('secondary_keywords') or parsed.get('keywords', [])
# Extract tags and categories from AI response
tags_from_response = parsed.get('tags', [])
categories_from_response = parsed.get('categories', [])
else:
# Plain text response
content_html = str(parsed)
@@ -187,6 +191,8 @@ class GenerateContentFunction(BaseAIFunction):
meta_description = None
primary_keyword = None
secondary_keywords = []
tags_from_response = []
categories_from_response = []
# Calculate word count
word_count = 0
@@ -222,8 +228,51 @@ class GenerateContentFunction(BaseAIFunction):
if task.taxonomy_term:
content_record.taxonomy_terms.add(task.taxonomy_term)
# Link all keywords from task as taxonomy terms (if they have taxonomy mappings)
# This is optional - keywords are M2M on Task, not directly on Content
# Process tags from AI response
if tags_from_response and isinstance(tags_from_response, list):
from django.utils.text import slugify
for tag_name in tags_from_response:
if tag_name and isinstance(tag_name, str):
tag_name = tag_name.strip()
if tag_name:
try:
# Get or create tag taxonomy term
tag_obj, _ = ContentTaxonomy.objects.get_or_create(
site=task.site,
name=tag_name,
taxonomy_type='tag',
defaults={
'slug': slugify(tag_name),
'sector': task.sector,
'account': task.account,
}
)
content_record.taxonomy_terms.add(tag_obj)
except Exception as e:
logger.warning(f"Failed to add tag '{tag_name}': {e}")
# Process categories from AI response
if categories_from_response and isinstance(categories_from_response, list):
from django.utils.text import slugify
for category_name in categories_from_response:
if category_name and isinstance(category_name, str):
category_name = category_name.strip()
if category_name:
try:
# Get or create category taxonomy term
category_obj, _ = ContentTaxonomy.objects.get_or_create(
site=task.site,
name=category_name,
taxonomy_type='category',
defaults={
'slug': slugify(category_name),
'sector': task.sector,
'account': task.account,
}
)
content_record.taxonomy_terms.add(category_obj)
except Exception as e:
logger.warning(f"Failed to add category '{category_name}': {e}")
# STAGE 3: Update task status to completed
task.status = 'completed'

View File

@@ -707,6 +707,25 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
})
failed += 1
# Check if all images for the content are generated and update status to 'review'
if content_id and completed > 0:
try:
from igny8_core.business.content.models import Content, Images
content = Content.objects.get(id=content_id)
# Check if all images for this content are now generated
all_images = Images.objects.filter(content=content)
pending_images = all_images.filter(status='pending').count()
# If no pending images and content is still in draft, move to review
if pending_images == 0 and content.status == 'draft':
content.status = 'review'
content.save(update_fields=['status'])
logger.info(f"[process_image_generation_queue] Content #{content_id} status updated to 'review' (all images generated)")
except Exception as e:
logger.error(f"[process_image_generation_queue] Error updating content status: {str(e)}", exc_info=True)
# Final state
logger.info("=" * 80)
logger.info(f"process_image_generation_queue COMPLETED")

View File

@@ -235,6 +235,7 @@ class Content(SiteSectorBaseModel):
# Status tracking
STATUS_CHOICES = [
('draft', 'Draft'),
('review', 'Review'),
('published', 'Published'),
]
status = models.CharField(

View File

@@ -0,0 +1,27 @@
# Generated manually on 2025-11-28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('writer', '0009_add_word_count_to_tasks'),
]
operations = [
migrations.AlterField(
model_name='content',
name='status',
field=models.CharField(
choices=[
('draft', 'Draft'),
('review', 'Review'),
('published', 'Published')
],
db_index=True,
default='draft',
help_text='Content status',
max_length=50
),
),
]

View File

@@ -154,6 +154,9 @@ class ContentSerializer(serializers.ModelSerializer):
cluster_name = serializers.SerializerMethodField()
sector_name = serializers.SerializerMethodField()
taxonomy_terms_data = serializers.SerializerMethodField()
has_image_prompts = serializers.SerializerMethodField()
image_status = serializers.SerializerMethodField()
has_generated_images = serializers.SerializerMethodField()
site_id = serializers.IntegerField(write_only=True, required=False)
sector_id = serializers.IntegerField(write_only=True, required=False)
@@ -181,6 +184,9 @@ class ContentSerializer(serializers.ModelSerializer):
'site_id',
'sector_id',
'account_id',
'has_image_prompts',
'image_status',
'has_generated_images',
'created_at',
'updated_at',
]
@@ -239,6 +245,35 @@ class ContentSerializer(serializers.ModelSerializer):
}
for term in obj.taxonomy_terms.all()
]
def get_has_image_prompts(self, obj):
"""Check if content has any image prompts (images with prompts)"""
return obj.images.filter(prompt__isnull=False).exclude(prompt='').exists()
def get_image_status(self, obj):
"""Get image generation status: 'generated', 'pending', 'failed', or None"""
images = obj.images.all()
if not images.exists():
return None
# Check statuses
has_failed = images.filter(status='failed').exists()
has_generated = images.filter(status='generated').exists()
has_pending = images.filter(status='pending').exists()
# Priority: failed > pending > generated
if has_failed:
return 'failed'
elif has_pending:
return 'pending'
elif has_generated:
return 'generated'
return None
def get_has_generated_images(self, obj):
"""Check if content has any successfully generated images"""
return obj.images.filter(status='generated', image_url__isnull=False).exclude(image_url='').exists()
class ContentTaxonomySerializer(serializers.ModelSerializer):