from rest_framework.generics import ListAPIView from rest_framework.response import Response from django.shortcuts import get_object_or_404 from utils.pagination import NoPagination from ..models import HadisSect, HadisCategory from ..serializers import HadisCategorySectListSerializer, HadisCategoryTreeSerializer, CategorySerializer , HadisCategorySelectSerializer from ..docs import ( hadis_sect_list_swagger, hadis_category_tree_swagger, categories_list_swagger, categories_by_sect_swagger, categories_tree_by_sect_swagger, categories_tree_by_sect_source_swagger ) class HadisCategorySectListView(ListAPIView): """ API view to list all HadisSects grouped by sect_type (shia/sunni) """ queryset = HadisSect.objects.filter(is_active=True).order_by('order') serializer_class = HadisCategorySectListSerializer pagination_class = NoPagination @hadis_sect_list_swagger def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def list(self, request, *args, **kwargs): queryset = self.get_queryset() response = super().list(request, *args, **kwargs) lang = request.LANGUAGE_CODE # Group sects by type grouped_data = { 'shia': [], 'sunni': [] } for sect in queryset: sect_data = { 'id': sect.id, 'title': sect.title, } if sect.sect_type == HadisSect.SectType.SHIA: grouped_data['shia'].append(sect_data) elif sect.sect_type == HadisSect.SectType.SUNNI: grouped_data['sunni'].append(sect_data) # Create response with count and results response_data = { 'count': queryset.count(), 'results': grouped_data } return Response(response_data) class HadisCategoryTreeView(ListAPIView): """ API view to get all HadisCategory tree structure grouped by sect and source_type Returns all categories in a tree structure """ serializer_class = HadisCategoryTreeSerializer pagination_class = NoPagination @hadis_category_tree_swagger def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def get_queryset(self): return HadisCategory.objects.filter( parent__isnull=True, sect__is_active=True ).order_by('sect__order', 'order') def list(self, request, *args, **kwargs): queryset = self.get_queryset() grouped_data = {} serializer_instance = HadisCategoryTreeSerializer(context={'request': request}) # گروه‌بندی بر اساس sect for category in queryset: sect_id = str(category.sect.id) if sect_id not in grouped_data: # اضافه کردن اطلاعات sect grouped_data[sect_id] = { 'sect_info': { 'id': category.sect.id, 'sect_type': category.sect.sect_type, 'title': category.sect.title, 'description': category.sect.description }, 'source_types': [], 'categories': {} } # اضافه کردن source_type به لیست if category.source_type not in grouped_data[sect_id]['source_types']: grouped_data[sect_id]['source_types'].append(category.source_type) # گروه‌بندی categories بر اساس source_type if category.source_type not in grouped_data[sect_id]['categories']: grouped_data[sect_id]['categories'][category.source_type] = [] category_data = serializer_instance.to_dict(category) grouped_data[sect_id]['categories'][category.source_type].append(category_data) def count_children(children_list): count = 0 for item in children_list: count += 1 if 'children' in item and item['children']: count += count_children(item['children']) return count total_count = 0 for sect_data in grouped_data.values(): for source_categories in sect_data['categories'].values(): for item in source_categories: total_count += 1 if 'children' in item and item['children']: total_count += count_children(item['children']) response_data = { 'count': total_count, 'results': grouped_data } return Response(response_data) class HadisCategoryTreeNormalView(ListAPIView): """ Normal (paginated) tree view for HadisCategory. Unlike the sync view, this simply returns the root categories (filtered to active sects) with their nested children, and uses the project's default pagination. """ serializer_class = HadisCategoryTreeSerializer @hadis_category_tree_swagger def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def get_queryset(self): return HadisCategory.objects.filter( parent__isnull=True, sect__is_active=True ).order_by('sect__order', 'order') class HadisCategorySelectBySectView(ListAPIView): """ Tree view for HadisCategory filtered by sect_type and category slug. Returns the children categories of the specified category (by slug) within the sect_type. """ serializer_class = HadisCategorySelectSerializer @categories_tree_by_sect_swagger def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def get_queryset(self): sect_type = self.kwargs.get('sect_type') slug = self.kwargs.get('slug') # Find the parent category by slug and sect_type try: parent_category = HadisCategory.objects.get( slug=slug, sect__sect_type=sect_type, sect__is_active=True ) except HadisCategory.DoesNotExist: return HadisCategory.objects.none() # Return children of this category, filtered as before return HadisCategory.objects.filter( parent=parent_category, sect__sect_type=sect_type, sect__is_active=True ).order_by('order') class HadisCategorySelectBySectSourceView(ListAPIView): """ Tree view for HadisCategory filtered by sect_type, category slug and source_type. Returns the children categories of the specified category (by slug) within the sect_type, filtered by source_type. """ serializer_class = HadisCategorySelectSerializer @categories_tree_by_sect_source_swagger def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def get_queryset(self): sect_type = self.kwargs.get('sect_type') slug = self.kwargs.get('slug') source_type = self.kwargs.get('source_type') # Find the parent category by slug and sect_type try: parent_category = HadisCategory.objects.get( slug=slug, sect__sect_type=sect_type, sect__is_active=True ) except HadisCategory.DoesNotExist: return HadisCategory.objects.none() # Return children of this category, filtered by source_type return HadisCategory.objects.filter( parent=parent_category, sect__sect_type=sect_type, sect__is_active=True, source_type=source_type ).order_by('order') class CategoriesView(ListAPIView): """ API view to list all HadisCategories """ queryset = HadisCategory.objects.all() serializer_class = CategorySerializer @categories_list_swagger def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def list(self, request, *args, **kwargs): return super().list(request, *args, **kwargs) class CategoriesBySectView(ListAPIView): """ API view to list HadisCategories filtered by sect_type """ serializer_class = CategorySerializer def get_queryset(self): sect_type = self.kwargs.get('sect_type') return HadisCategory.objects.filter(sect__sect_type=sect_type) @categories_by_sect_swagger def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs)