You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
12 KiB
329 lines
12 KiB
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_type (shia/sunni)
|
|
for category in queryset:
|
|
sect_type = category.sect.sect_type
|
|
|
|
if sect_type not in grouped_data:
|
|
# ایجاد گروه برای هر sect_type
|
|
grouped_data[sect_type] = {
|
|
'sects': {},
|
|
'categories': {}
|
|
}
|
|
|
|
# اضافه کردن اطلاعات sect به گروه sect_type
|
|
sect_id = str(category.sect.id)
|
|
if sect_id not in grouped_data[sect_type]['sects']:
|
|
grouped_data[sect_type]['sects'][sect_id] = {
|
|
'id': category.sect.id,
|
|
'sect_type': category.sect.sect_type,
|
|
'title': category.sect.title,
|
|
'description': category.sect.description,
|
|
'order': category.sect.order
|
|
}
|
|
|
|
# گروهبندی categories بر اساس source_type
|
|
if category.source_type not in grouped_data[sect_type]['categories']:
|
|
grouped_data[sect_type]['categories'][category.source_type] = []
|
|
|
|
category_data = self.build_enhanced_category_tree(category, serializer_instance)
|
|
grouped_data[sect_type]['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_type_data in grouped_data.values():
|
|
for source_categories in sect_type_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)
|
|
|
|
def build_enhanced_category_tree(self, category, serializer_instance):
|
|
"""Build enhanced category tree with father category info and hadis details"""
|
|
base_data = serializer_instance.to_dict(category)
|
|
|
|
# Enhance children with additional information
|
|
enhanced_children = []
|
|
for child_data in base_data.get('children', []):
|
|
enhanced_child = self.enhance_child_data(child_data, category, serializer_instance)
|
|
enhanced_children.append(enhanced_child)
|
|
|
|
base_data['children'] = enhanced_children
|
|
return base_data
|
|
|
|
def enhance_child_data(self, child_data, parent_category, serializer_instance):
|
|
"""Enhance child data with father category info and hadis details"""
|
|
from ..models import Hadis
|
|
|
|
# Add father category information
|
|
child_data['father_category'] = {
|
|
'id': parent_category.id,
|
|
'name': parent_category.title,
|
|
'sect_id': parent_category.sect.id,
|
|
'sect_type': parent_category.sect.sect_type,
|
|
'source_type': parent_category.source_type
|
|
}
|
|
|
|
# If this child has no children but has hadis, add hadis details
|
|
if not child_data.get('children', []) and child_data.get('has_hadis', False):
|
|
try:
|
|
# Get the category object
|
|
from ..models import HadisCategory
|
|
child_category = HadisCategory.objects.get(id=child_data['id'])
|
|
|
|
# Get hadis for this category
|
|
hadis_list = Hadis.objects.filter(
|
|
category=child_category,
|
|
status=True
|
|
).order_by('number')
|
|
|
|
hadis_details = []
|
|
for hadis in hadis_list:
|
|
hadis_detail = {
|
|
'id': hadis.id,
|
|
'title': hadis.title,
|
|
'title_narrator': hadis.title_narrator,
|
|
'text': hadis.text,
|
|
'translation': hadis.get_translation(
|
|
self.request.LANGUAGE_CODE if hasattr(self, 'request') and self.request else 'en'
|
|
),
|
|
'share_link': hadis.share_link
|
|
}
|
|
hadis_details.append(hadis_detail)
|
|
|
|
child_data['hadis_details'] = hadis_details
|
|
|
|
except Exception as e:
|
|
# If there's any error, just continue without hadis details
|
|
pass
|
|
|
|
# Recursively enhance children's children
|
|
if child_data.get('children', []):
|
|
enhanced_grandchildren = []
|
|
try:
|
|
from ..models import HadisCategory
|
|
child_category = HadisCategory.objects.get(id=child_data['id'])
|
|
|
|
for grandchild_data in child_data['children']:
|
|
enhanced_grandchild = self.enhance_child_data(grandchild_data, child_category, serializer_instance)
|
|
enhanced_grandchildren.append(enhanced_grandchild)
|
|
except:
|
|
# If there's an error, keep original children
|
|
enhanced_grandchildren = child_data['children']
|
|
|
|
child_data['children'] = enhanced_grandchildren
|
|
|
|
return child_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)
|