fixed usage limits of used
This commit is contained in:
@@ -0,0 +1,87 @@
|
|||||||
|
"""
|
||||||
|
Management command to backfill usage tracking for existing content.
|
||||||
|
Usage: python manage.py backfill_usage [account_id]
|
||||||
|
"""
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.apps import apps
|
||||||
|
from django.db import transaction
|
||||||
|
from igny8_core.auth.models import Account
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Backfill usage tracking for existing content'
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'account_id',
|
||||||
|
nargs='?',
|
||||||
|
type=int,
|
||||||
|
help='Account ID to backfill (optional, processes all accounts if not provided)'
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
account_id = options.get('account_id')
|
||||||
|
|
||||||
|
if account_id:
|
||||||
|
accounts = Account.objects.filter(id=account_id).select_related('plan')
|
||||||
|
if not accounts.exists():
|
||||||
|
self.stdout.write(self.style.ERROR(f'Account {account_id} not found'))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
accounts = Account.objects.filter(plan__isnull=False).select_related('plan')
|
||||||
|
|
||||||
|
ContentIdeas = apps.get_model('planner', 'ContentIdeas')
|
||||||
|
Content = apps.get_model('writer', 'Content')
|
||||||
|
Images = apps.get_model('writer', 'Images')
|
||||||
|
|
||||||
|
total_accounts = accounts.count()
|
||||||
|
self.stdout.write(f'Processing {total_accounts} account(s)...\n')
|
||||||
|
|
||||||
|
for account in accounts:
|
||||||
|
self.stdout.write('=' * 60)
|
||||||
|
self.stdout.write(f'Account: {account.name} (ID: {account.id})')
|
||||||
|
self.stdout.write(f'Plan: {account.plan.name if account.plan else "No Plan"}')
|
||||||
|
self.stdout.write('=' * 60)
|
||||||
|
|
||||||
|
# Count content ideas
|
||||||
|
ideas_count = ContentIdeas.objects.filter(account=account).count()
|
||||||
|
self.stdout.write(f'Content Ideas: {ideas_count}')
|
||||||
|
|
||||||
|
# Count content words
|
||||||
|
from django.db.models import Sum
|
||||||
|
total_words = Content.objects.filter(account=account).aggregate(
|
||||||
|
total=Sum('word_count')
|
||||||
|
)['total'] or 0
|
||||||
|
self.stdout.write(f'Content Words: {total_words}')
|
||||||
|
|
||||||
|
# Count images
|
||||||
|
total_images = Images.objects.filter(account=account).count()
|
||||||
|
images_with_prompts = Images.objects.filter(
|
||||||
|
account=account, prompt__isnull=False
|
||||||
|
).exclude(prompt='').count()
|
||||||
|
self.stdout.write(f'Total Images: {total_images}')
|
||||||
|
self.stdout.write(f'Images with Prompts: {images_with_prompts}')
|
||||||
|
|
||||||
|
# Update account usage fields
|
||||||
|
with transaction.atomic():
|
||||||
|
account.usage_content_ideas = ideas_count
|
||||||
|
account.usage_content_words = total_words
|
||||||
|
account.usage_images_basic = total_images
|
||||||
|
account.usage_images_premium = 0 # Premium not implemented yet
|
||||||
|
account.usage_image_prompts = images_with_prompts
|
||||||
|
account.save(update_fields=[
|
||||||
|
'usage_content_ideas', 'usage_content_words',
|
||||||
|
'usage_images_basic', 'usage_images_premium', 'usage_image_prompts',
|
||||||
|
'updated_at'
|
||||||
|
])
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('\n✅ Updated usage tracking:'))
|
||||||
|
self.stdout.write(f' usage_content_ideas: {account.usage_content_ideas}')
|
||||||
|
self.stdout.write(f' usage_content_words: {account.usage_content_words}')
|
||||||
|
self.stdout.write(f' usage_images_basic: {account.usage_images_basic}')
|
||||||
|
self.stdout.write(f' usage_images_premium: {account.usage_images_premium}')
|
||||||
|
self.stdout.write(f' usage_image_prompts: {account.usage_image_prompts}\n')
|
||||||
|
|
||||||
|
self.stdout.write('=' * 60)
|
||||||
|
self.stdout.write(self.style.SUCCESS('✅ Backfill complete!'))
|
||||||
|
self.stdout.write('=' * 60)
|
||||||
@@ -459,8 +459,10 @@ class Images(SoftDeletableModel, SiteSectorBaseModel):
|
|||||||
all_objects = models.Manager()
|
all_objects = models.Manager()
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
"""Automatically set account, site, and sector from content or task"""
|
"""Track image usage when creating new images"""
|
||||||
# Prefer content over task
|
is_new = self.pk is None
|
||||||
|
|
||||||
|
# Automatically set account, site, and sector from content or task
|
||||||
if self.content:
|
if self.content:
|
||||||
self.account = self.content.account
|
self.account = self.content.account
|
||||||
self.site = self.content.site
|
self.site = self.content.site
|
||||||
@@ -469,7 +471,44 @@ class Images(SoftDeletableModel, SiteSectorBaseModel):
|
|||||||
self.account = self.task.account
|
self.account = self.task.account
|
||||||
self.site = self.task.site
|
self.site = self.task.site
|
||||||
self.sector = self.task.sector
|
self.sector = self.task.sector
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
# Increment usage for new images
|
||||||
|
if is_new:
|
||||||
|
from igny8_core.business.billing.services.limit_service import LimitService
|
||||||
|
try:
|
||||||
|
account = self.account
|
||||||
|
if account:
|
||||||
|
# Track image prompt usage
|
||||||
|
if self.prompt:
|
||||||
|
LimitService.increment_usage(
|
||||||
|
account=account,
|
||||||
|
limit_type='image_prompts',
|
||||||
|
amount=1,
|
||||||
|
metadata={
|
||||||
|
'image_id': self.id,
|
||||||
|
'image_type': self.image_type,
|
||||||
|
'content_id': self.content.id if self.content else None,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Track basic image usage (for now, all images are counted as basic)
|
||||||
|
# TODO: Implement premium image tracking when premium models are used
|
||||||
|
LimitService.increment_usage(
|
||||||
|
account=account,
|
||||||
|
limit_type='images_basic',
|
||||||
|
amount=1,
|
||||||
|
metadata={
|
||||||
|
'image_id': self.id,
|
||||||
|
'image_type': self.image_type,
|
||||||
|
'content_id': self.content.id if self.content else None,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.error(f"Error incrementing image usage for image {self.id}: {str(e)}")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
content_title = self.content.title if self.content else None
|
content_title = self.content.title if self.content else None
|
||||||
|
|||||||
@@ -242,6 +242,32 @@ class ContentIdeas(SoftDeletableModel, SiteSectorBaseModel):
|
|||||||
objects = SoftDeleteManager()
|
objects = SoftDeleteManager()
|
||||||
all_objects = models.Manager()
|
all_objects = models.Manager()
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
"""Track content ideas usage when creating new ideas"""
|
||||||
|
is_new = self.pk is None
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
# Increment usage for new content ideas
|
||||||
|
if is_new:
|
||||||
|
from igny8_core.business.billing.services.limit_service import LimitService
|
||||||
|
try:
|
||||||
|
account = self.site.account if self.site else self.account
|
||||||
|
if account:
|
||||||
|
LimitService.increment_usage(
|
||||||
|
account=account,
|
||||||
|
limit_type='content_ideas',
|
||||||
|
amount=1,
|
||||||
|
metadata={
|
||||||
|
'idea_id': self.id,
|
||||||
|
'idea_title': self.idea_title,
|
||||||
|
'site_id': self.site.id if self.site else None,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.error(f"Error incrementing content ideas usage for idea {self.id}: {str(e)}")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.idea_title
|
return self.idea_title
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user