ai fucntiosn adn otehr atuoamtion fixes
This commit is contained in:
@@ -711,6 +711,113 @@ class KeywordViewSet(SiteSectorModelViewSet):
|
||||
request=request
|
||||
)
|
||||
|
||||
@action(detail=False, methods=['get'], url_path='stats', url_name='stats')
|
||||
def stats(self, request):
|
||||
"""
|
||||
Get aggregate statistics for keywords.
|
||||
Returns total keywords count and total volume across all keywords for the current site.
|
||||
Used for header metrics display.
|
||||
"""
|
||||
from django.db.models import Sum, Count, Case, When, F, IntegerField
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
queryset = self.get_queryset()
|
||||
|
||||
# Aggregate keyword stats
|
||||
keyword_stats = queryset.aggregate(
|
||||
total_keywords=Count('id'),
|
||||
total_volume=Sum(
|
||||
Case(
|
||||
When(volume_override__isnull=False, then=F('volume_override')),
|
||||
default=F('seed_keyword__volume'),
|
||||
output_field=IntegerField()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
'total_keywords': keyword_stats['total_keywords'] or 0,
|
||||
'total_volume': keyword_stats['total_volume'] or 0,
|
||||
},
|
||||
request=request
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in keywords stats: {str(e)}", exc_info=True)
|
||||
return error_response(
|
||||
error=f'Failed to fetch keyword stats: {str(e)}',
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
request=request
|
||||
)
|
||||
|
||||
@action(detail=False, methods=['get'], url_path='filter_options', url_name='filter_options')
|
||||
def filter_options(self, request):
|
||||
"""
|
||||
Get distinct filter values from current data.
|
||||
Returns only countries and statuses that exist in the current site's keywords.
|
||||
"""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
queryset = self.get_queryset()
|
||||
|
||||
# Get distinct countries from seed_keyword (use set for proper deduplication)
|
||||
countries = list(set(queryset.values_list('seed_keyword__country', flat=True)))
|
||||
countries = sorted([c for c in countries if c]) # Sort and filter nulls
|
||||
|
||||
# Map country codes to display names
|
||||
from igny8_core.auth.models import SeedKeyword
|
||||
country_choices = dict(SeedKeyword.COUNTRY_CHOICES)
|
||||
country_options = [
|
||||
{'value': c, 'label': country_choices.get(c, c)}
|
||||
for c in countries
|
||||
]
|
||||
|
||||
# Get distinct statuses (use set for proper deduplication)
|
||||
statuses = list(set(queryset.values_list('status', flat=True)))
|
||||
statuses = sorted([s for s in statuses if s]) # Sort and filter nulls
|
||||
status_labels = {
|
||||
'new': 'New',
|
||||
'mapped': 'Mapped',
|
||||
}
|
||||
status_options = [
|
||||
{'value': s, 'label': status_labels.get(s, s.title())}
|
||||
for s in statuses
|
||||
]
|
||||
|
||||
# Get distinct clusters (use set for proper deduplication)
|
||||
cluster_ids = list(set(
|
||||
queryset.exclude(cluster_id__isnull=True)
|
||||
.values_list('cluster_id', flat=True)
|
||||
))
|
||||
|
||||
clusters = Clusters.objects.filter(id__in=cluster_ids).values('id', 'name').order_by('name')
|
||||
cluster_options = [
|
||||
{'value': str(c['id']), 'label': c['name']}
|
||||
for c in clusters
|
||||
]
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
'countries': country_options,
|
||||
'statuses': status_options,
|
||||
'clusters': cluster_options,
|
||||
},
|
||||
request=request
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in filter_options: {str(e)}", exc_info=True)
|
||||
return error_response(
|
||||
error=f'Failed to fetch filter options: {str(e)}',
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
request=request
|
||||
)
|
||||
|
||||
@action(detail=False, methods=['post'], url_path='auto_cluster', url_name='auto_cluster')
|
||||
def auto_cluster(self, request):
|
||||
"""Auto-cluster keywords using ClusteringService"""
|
||||
|
||||
Reference in New Issue
Block a user