diff --git a/apps/article/views.py b/apps/article/views.py index 1be4b2f..882a2de 100755 --- a/apps/article/views.py +++ b/apps/article/views.py @@ -15,6 +15,7 @@ class ArticleCategoryListAPIView(generics.ListAPIView): @swagger_auto_schema( operation_description="Get a list of all active article categories", + tags=["Dobodbi - Article"], responses={ 200: openapi.Response( description="List of article categories", @@ -34,6 +35,18 @@ class PinnedArticleCollectionListView(generics.ListAPIView): permission_classes = (IsAuthenticated,) pagination_class = NoPagination + @swagger_auto_schema( + operation_description="Get a list of pinned article collections", + tags=["Dobodbi - Article"], + responses={ + 200: openapi.Response( + description="List of pinned article collections", + schema=PinnedArticleCollectionSerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) def get_queryset(self): return PinnedArticleCollection.objects.filter( @@ -67,7 +80,20 @@ class MiddleArticleCollectionListView(generics.ListAPIView): serializer_class = MiddleArticleCollectionSerializer permission_classes = (IsAuthenticated,) pagination_class = NoPagination - + + @swagger_auto_schema( + operation_description="Get a list of middle article collections", + tags=["Dobodbi - Article"], + responses={ + 200: openapi.Response( + description="List of middle article collections", + schema=MiddleArticleCollectionSerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return ArticleCollection.objects.filter( status=True, @@ -83,6 +109,7 @@ class ArticleListAPIView(generics.ListAPIView): @swagger_auto_schema( operation_description="Get a list of articles with optional filtering and sorting", + tags=["Dobodbi - Article"], manual_parameters=[ openapi.Parameter( name='category', @@ -186,7 +213,20 @@ class ArticleDetailAPIView(generics.RetrieveAPIView): serializer_class = ArticleDetailSerializer permission_classes = (IsAuthenticated,) lookup_field = 'slug' - + + @swagger_auto_schema( + operation_description="Get article details by slug", + tags=["Dobodbi - Article"], + responses={ + 200: openapi.Response( + description="Article details", + schema=ArticleDetailSerializer() + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return Article.objects.filter(status=True) diff --git a/apps/blog/views.py b/apps/blog/views.py index 4096fbd..dd004e4 100644 --- a/apps/blog/views.py +++ b/apps/blog/views.py @@ -21,6 +21,7 @@ class BlogListAPIView(ListAPIView): @swagger_auto_schema( operation_description="List blogs with optional search and sort_by filters", + tags=["Imam-Javad - Blog"], manual_parameters=[ openapi.Parameter( name='search', @@ -81,6 +82,7 @@ class RelatedBlogsAPIView(GenericAPIView): @swagger_auto_schema( operation_description="Get up to 10 random related blogs for the given blog_id", + tags=["Imam-Javad - Blog"], manual_parameters=[ openapi.Parameter( name='blog_id', @@ -134,6 +136,7 @@ class BlogDetailBySlugAPIView(GenericAPIView): @swagger_auto_schema( operation_description="Get blog details by slug and increment view count", + tags=["Imam-Javad - Blog"], manual_parameters=[ openapi.Parameter( name='slug', diff --git a/apps/bookmark/urls.py b/apps/bookmark/urls.py index 8117567..4ee0b77 100644 --- a/apps/bookmark/urls.py +++ b/apps/bookmark/urls.py @@ -12,6 +12,6 @@ urlpatterns = [ # Rate URLs path('rate/add/', AddRateView.as_view(), name='add_rate'), path('rate/remove/', RemoveRateView.as_view(), name='remove_rate'), - # path('rate/status/', RateStatusView.as_view(), name='rate_status'), - # path('rate/average/', AverageRateView.as_view(), name='average_rate'), + path('rate/status/', RateStatusView.as_view(), name='rate_status'), + path('rate/average/', AverageRateView.as_view(), name='average_rate'), ] \ No newline at end of file diff --git a/apps/bookmark/views/bookmark.py b/apps/bookmark/views/bookmark.py index 59904ca..592793c 100644 --- a/apps/bookmark/views/bookmark.py +++ b/apps/bookmark/views/bookmark.py @@ -21,6 +21,7 @@ class AddBookmarkView(CreateAPIView): @swagger_auto_schema( operation_description="Add a bookmark for a specific content in a service. If the bookmark already exists but is inactive, it will be reactivated.", + tags=["Dobodbi - Bookmarks"], request_body=BookmarkSerializer, responses={ 201: "Bookmark created successfully.", @@ -28,6 +29,8 @@ class AddBookmarkView(CreateAPIView): 400: "Invalid input." } ) + def post(self, request, pk, *args, **kwargs): + return super().post(request,*args, **kwargs) def create(self, request, *args, **kwargs): service = request.data.get('service') content_id = request.data.get('content_id') @@ -78,6 +81,7 @@ class RemoveBookmarkView(DestroyAPIView): @swagger_auto_schema( operation_description="Deactivate a bookmark by setting its status to False using content_id and user.", + tags=["Dobodbi - Bookmarks"], request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ @@ -92,6 +96,8 @@ class RemoveBookmarkView(DestroyAPIView): 404: "Bookmark not found or already inactive." } ) + def delete(self,request,*args, **kwargs): + return super().delete(request,*args, **kwargs) def get_object(self): service = self.request.data.get('service') content_id = self.request.data.get('content_id') @@ -126,6 +132,7 @@ class BookmarkStatusView(APIView): @swagger_auto_schema( operation_description="Return the count of bookmarks for each service for the current user.", + tags=["Dobodbi - Bookmarks"], responses={ 200: "A list of bookmark counts for each service.", } diff --git a/apps/bookmark/views/rate.py b/apps/bookmark/views/rate.py index fa0ab4d..2e691b2 100644 --- a/apps/bookmark/views/rate.py +++ b/apps/bookmark/views/rate.py @@ -15,6 +15,7 @@ class AddRateView(APIView): @swagger_auto_schema( operation_description="Add or update a rate for a content.", + tags=["Dobodbi - Bookmarks"], request_body=RateSerializer, responses={ 201: "Rate created successfully.", @@ -39,6 +40,7 @@ class RemoveRateView(APIView): @swagger_auto_schema( operation_description="Remove a rate by setting its status to False.", + tags=["Dobodbi - Bookmarks"], request_body=RateStatusSerializer, responses={ 200: "Rate removed successfully.", @@ -74,7 +76,16 @@ class RateStatusView(APIView): API view for checking if a user has rated a content and getting the rate value. """ permission_classes = [IsAuthenticated] - + + @swagger_auto_schema( + operation_description="Check if a user has rated a content and get the rate value.", + tags=["Dobodbi - Bookmarks"], + request_body=RateStatusSerializer, + responses={ + 200: "Rate status information.", + 400: "Invalid input." + } + ) def post(self, request): """ Check if a user has rated a content and get the rate value. @@ -93,6 +104,16 @@ class AverageRateView(APIView): """ API view for getting the average rate of a content. """ + + @swagger_auto_schema( + operation_description="Get the average rate of a content.", + tags=["Dobodbi - Bookmarks"], + request_body=AverageRateSerializer, + responses={ + 200: "Average rate information.", + 400: "Invalid input." + } + ) def post(self, request): """ Get the average rate of a content. diff --git a/apps/certificate/views.py b/apps/certificate/views.py index 4e12f21..7cbbbc3 100644 --- a/apps/certificate/views.py +++ b/apps/certificate/views.py @@ -1,4 +1,6 @@ from rest_framework import generics, permissions +from drf_yasg.utils import swagger_auto_schema +from drf_yasg import openapi from apps.certificate.models import Certificate from apps.certificate.serializers import CertificateRequestSerializer, CertificateSerializer @@ -10,6 +12,18 @@ class CertificateRequestView(generics.CreateAPIView): serializer_class = CertificateRequestSerializer permission_classes = [permissions.IsAuthenticated] + @swagger_auto_schema( + operation_description="Request a certificate for completed course", + tags=["Imam-Javad - Certificate"], + responses={ + 201: openapi.Response( + description="Certificate request created successfully" + ) + } + ) + def post(self, request, *args, **kwargs): + return super().post(request, *args, **kwargs) + def perform_create(self, serializer): serializer.save(student=self.request.user) @@ -19,6 +33,19 @@ class UserCertificatesListView(generics.ListAPIView): serializer_class = CertificateSerializer permission_classes = [permissions.IsAuthenticated] + @swagger_auto_schema( + operation_description="Get list of user's certificates", + tags=["Imam-Javad - Certificate"], + responses={ + 200: openapi.Response( + description="List of user certificates", + schema=CertificateSerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return Certificate.objects.filter(student=self.request.user).order_by('-created_at') \ No newline at end of file diff --git a/apps/course/views/course.py b/apps/course/views/course.py index 34bb494..b631055 100644 --- a/apps/course/views/course.py +++ b/apps/course/views/course.py @@ -49,6 +49,7 @@ class CourseCategoryAPIView(ListAPIView): @swagger_auto_schema( operation_description=doc_course_category(), + tags=["Imam-Javad - Course"] ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) @@ -62,6 +63,7 @@ class CourseListAPIView(ListAPIView): search_fields = ['title', 'category__name', 'professor__fullname'] @swagger_auto_schema( + tags=['Imam-Javad - Course'], operation_description=doc_course_list(), manual_parameters=[ openapi.Parameter( @@ -98,7 +100,7 @@ class CourseListAPIView(ListAPIView): ), ]) def get(self, request, *args, **kwargs): - return super().get(request, *args, **kwargs) + return self.list(request, *args, **kwargs) def get_queryset(self): """ @@ -141,6 +143,19 @@ class CourseDetailAPIView(RetrieveAPIView): serializer_class = CourseDetailSerializer lookup_field = "slug" + @swagger_auto_schema( + tags=["Imam-Javad - Course"], + operation_description="Get detailed information about a specific course", + responses={ + 200: openapi.Response( + description="Course details", + schema=CourseDetailSerializer() + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): """ Optimized queryset with select_related and prefetch_related for all relationships @@ -159,6 +174,7 @@ class CourseDetailAPIView(RetrieveAPIView): @swagger_auto_schema( operation_description=doc_course_detail(), + tags=['Imam-Javad - Course'], ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) @@ -181,6 +197,7 @@ class MyCourseListAPIView(ListAPIView): ], operation_description=doc_courses_my_courses(), operation_summary="Home", + tags=['Imam-Javad - Course'] ) def get(self, request, *args, **kwargs): @@ -243,6 +260,7 @@ class AttachmentListAPIView(ListAPIView): serializer_class = CourseAttachmentSerializer @swagger_auto_schema( + tags=['Imam-Javad - Course'], manual_parameters=[ openapi.Parameter( 'slug', openapi.IN_PATH, @@ -275,9 +293,36 @@ class AttachmentListAPIView(ListAPIView): class GlossaryListAPIView(ListAPIView): serializer_class = CourseGlossarySerializer - filter_backends = [SearchFilter] + filter_backends = [SearchFilter] search_fields = ['glossary__title', 'glossary__description'] - + + @swagger_auto_schema( + operation_description="Get glossary terms for a specific course", + tags=["Imam-Javad - Course"], + manual_parameters=[ + openapi.Parameter( + 'slug', openapi.IN_PATH, + description="Course slug", + type=openapi.TYPE_STRING, + required=True + ), + openapi.Parameter( + 'search', openapi.IN_QUERY, + description="Search in glossary title or description", + type=openapi.TYPE_STRING, + required=False + ) + ], + responses={ + 200: openapi.Response( + description="List of glossary terms", + schema=CourseGlossarySerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): """ Optimized queryset with select_related for glossary relationship @@ -300,6 +345,7 @@ class CourseOnlineClassTokenAPIView(GenericAPIView): serializer_class = OnlineClassTokenCreateSerializer @swagger_auto_schema( + tags=['Imam-Javad - Course'], operation_description="Generate a temporary entry token for an online class.", request_body=OnlineClassTokenCreateSerializer, responses={ @@ -367,6 +413,7 @@ class CourseOnlineClassTokenValidateAPIView(GenericAPIView): return [AllowAny()] @swagger_auto_schema( + tags=['Imam-Javad - Course'], operation_description="Get course and user data for authenticated user.", manual_parameters=[ openapi.Parameter( @@ -419,6 +466,7 @@ class CourseOnlineClassTokenValidateAPIView(GenericAPIView): }, status=status.HTTP_200_OK) @swagger_auto_schema( + tags=['Imam-Javad - Course'], operation_description="Validate an online class entry token and return course/user data.", request_body=OnlineClassTokenVerifySerializer, responses={ diff --git a/apps/course/views/lesson.py b/apps/course/views/lesson.py index 94be924..111cbe5 100644 --- a/apps/course/views/lesson.py +++ b/apps/course/views/lesson.py @@ -21,6 +21,7 @@ class LessonListView(ListAPIView): @swagger_auto_schema( operation_description=doc_courses_lesson(), + tags=['Imam-Javad - Course'], ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) @@ -49,6 +50,24 @@ class LessonListView(ListAPIView): class LessonDetailView(RetrieveAPIView): serializer_class = CourseLessonSerializer + @swagger_auto_schema( + operation_description="Get detailed lesson information with navigation data", + tags=["Imam-Javad - Course"], + manual_parameters=[ + openapi.Parameter( + 'id', openapi.IN_PATH, + description="Lesson ID", + type=openapi.TYPE_INTEGER, + required=True + ) + ], + responses={ + 200: openapi.Response( + description="Lesson details with navigation information", + schema=CourseLessonSerializer() + ) + } + ) def get(self, request, *args, **kwargs): """ Optimized lesson detail view with select_related for relationships @@ -91,6 +110,8 @@ class LessonCompletionCreateAPIView(GenericAPIView): @swagger_auto_schema( + operation_description="Mark a lesson as completed", + tags=["Imam-Javad - Course"], request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['lesson_id'], diff --git a/apps/course/views/live_session.py b/apps/course/views/live_session.py index 723036d..2ea2a11 100644 --- a/apps/course/views/live_session.py +++ b/apps/course/views/live_session.py @@ -8,6 +8,8 @@ from rest_framework import status from rest_framework.generics import GenericAPIView from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response +from drf_yasg.utils import swagger_auto_schema +from drf_yasg import openapi from apps.course.models import Course, CourseLiveSession, Participant, LiveSessionRecording from apps.course.serializers import LiveSessionRoomCreateSerializer, LiveSessionTokenSerializer, LiveSessionRecordedFileSerializer, LiveSessionRecordingSerializer @@ -21,6 +23,23 @@ class CourseLiveSessionRoomCreateAPIView(GenericAPIView): permission_classes = [IsAuthenticated] serializer_class = LiveSessionRoomCreateSerializer + @swagger_auto_schema( + operation_description="Create a live session room for a course", + tags=["Imam-Javad - Course"], + manual_parameters=[ + openapi.Parameter( + 'slug', openapi.IN_PATH, + description="Course slug", + type=openapi.TYPE_STRING, + required=True + ) + ], + responses={ + 201: openapi.Response( + description="Live session room created successfully" + ) + } + ) def post(self, request, slug, *args, **kwargs): logger.info(f"[LiveSession Create] Request from user_id={request.user.id} for course={slug}") @@ -173,6 +192,15 @@ class CourseLiveSessionTokenAPIView(GenericAPIView): permission_classes = [IsAuthenticated] serializer_class = LiveSessionTokenSerializer + @swagger_auto_schema( + operation_description="Generate access token for live session", + tags=["Imam-Javad - Course"], + responses={ + 200: openapi.Response( + description="Live session token generated successfully" + ) + } + ) def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) @@ -282,6 +310,23 @@ class CourseLiveSessionRecordedFileAPIView(GenericAPIView): permission_classes = [IsAuthenticated] serializer_class = LiveSessionRecordingSerializer + @swagger_auto_schema( + operation_description="Update recorded file for live session", + tags=["Imam-Javad - Course"], + manual_parameters=[ + openapi.Parameter( + 'course_id', openapi.IN_PATH, + description="Course ID", + type=openapi.TYPE_INTEGER, + required=True + ) + ], + responses={ + 200: openapi.Response( + description="Recorded file updated successfully" + ) + } + ) def patch(self, request, course_id, *args, **kwargs): logger.info(f"[LiveSession Recorded File] Request from user_id={request.user.id} for course_id={course_id}") diff --git a/apps/course/views/participant.py b/apps/course/views/participant.py index 74f257f..b591f76 100644 --- a/apps/course/views/participant.py +++ b/apps/course/views/participant.py @@ -19,7 +19,10 @@ class CourseParticipantsView(generics.ListAPIView): @swagger_auto_schema( operation_description=doc_course_participants(), + tags=['Imam-Javad - Course'], ) + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) def get_queryset(self): """ Optimized queryset with select_related for course relationship diff --git a/apps/course/views/professor.py b/apps/course/views/professor.py index 317a66d..4b51193 100644 --- a/apps/course/views/professor.py +++ b/apps/course/views/professor.py @@ -27,6 +27,7 @@ class ProfessorListAPIView(ListAPIView): @swagger_auto_schema( operation_description='دریافت فهرست استادها به همراه تعداد دوره‌ها و درس‌های فعال هر استاد.', + tags=['Imam-Javad - Course'], responses={ 200: openapi.Response( description='فهرست صفحه‌بندی‌شده‌ی استادها.', @@ -72,6 +73,7 @@ class ProfessorDetailAPIView(RetrieveAPIView): @swagger_auto_schema( operation_description='دریافت جزئیات یک استاد بر اساس اسلاگ.', + tags=['Imam-Javad - Course'], responses={ 200: openapi.Response( description='اطلاعات کامل استاد.', @@ -119,6 +121,7 @@ class ProfessorCourseListAPIView(ListAPIView): @swagger_auto_schema( operation_description='دریافت فهرست دوره‌های فعال یک استاد مشخص‌شده با اسلاگ.', + tags=['Imam-Javad - Course'], responses={ 200: openapi.Response( description='فهرست صفحه‌بندی‌شده‌ی دوره‌ها.', diff --git a/apps/course/views/webhook.py b/apps/course/views/webhook.py index ead1190..68e3f64 100644 --- a/apps/course/views/webhook.py +++ b/apps/course/views/webhook.py @@ -14,6 +14,8 @@ from rest_framework import status from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import AllowAny +from drf_yasg.utils import swagger_auto_schema +from drf_yasg import openapi from apps.course.models import CourseLiveSession, LiveSessionUser, Course, Participant from apps.account.models import User @@ -26,7 +28,7 @@ logger = logging.getLogger(__name__) class PlugNMeetWebhookAPIView(APIView): """ Webhook endpoint to receive events from PlugNMeet server. - + Events handled: - room_finished: Close the live session - participant_joined: Create LiveSessionUser entry @@ -35,6 +37,15 @@ class PlugNMeetWebhookAPIView(APIView): """ permission_classes = [AllowAny] + @swagger_auto_schema( + operation_description="Handle webhook events from PlugNMeet server for live sessions", + tags=["Imam-Javad - Course"], + responses={ + 200: openapi.Response(description="Webhook processed successfully"), + 400: openapi.Response(description="Invalid webhook signature or data"), + 500: openapi.Response(description="Internal server error") + } + ) def post(self, request, *args, **kwargs): logger.info(f"[PlugNMeet Webhook] Received webhook request") diff --git a/apps/dobodbi_calendar/views.py b/apps/dobodbi_calendar/views.py index ccbf662..df97681 100644 --- a/apps/dobodbi_calendar/views.py +++ b/apps/dobodbi_calendar/views.py @@ -11,6 +11,8 @@ from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.response import Response from rest_framework.views import APIView, status +from drf_yasg.utils import swagger_auto_schema +from drf_yasg import openapi from apps.account.models import User from apps.dobodbi_calendar.models import CalendarOccasions @@ -24,6 +26,26 @@ class CalendarList(ListAPIView): permission_classes = (AllowAny,) + @swagger_auto_schema( + operation_description="Get list of calendar occasions", + tags=["Dobodbi - Calendar"], + manual_parameters=[ + openapi.Parameter( + 'last_updated', openapi.IN_QUERY, + description="Filter occasions updated after this timestamp", + type=openapi.TYPE_STRING, + required=False + ) + ], + responses={ + 200: openapi.Response( + description="List of calendar occasions with metadata" + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + # @method_decorator(cache_page(60 * 15)) # Cache for 1 Hour # def dispatch(self, *args, **kwargs): # return super().dispatch(*args, **kwargs) @@ -60,7 +82,16 @@ class CalendarList(ListAPIView): class AdjustmentConfigView(APIView): permission_classes = (AllowAny,) - + + @swagger_auto_schema( + operation_description="Get calendar adjustment configuration", + tags=["Dobodbi - Calendar"], + responses={ + 200: openapi.Response( + description="Calendar adjustment configuration" + ) + } + ) def get(self, request): adjustment_config = get_config('calendar__Adjustment') return Response(json.loads(adjustment_config)) diff --git a/apps/hadis/docs.py b/apps/hadis/docs.py index 5c0198b..533f833 100644 --- a/apps/hadis/docs.py +++ b/apps/hadis/docs.py @@ -6,7 +6,7 @@ from rest_framework import status hadis_sect_list_swagger = swagger_auto_schema( operation_description="Get list of all active Hadis sects grouped by sect type (Shia/Sunni)", operation_summary="List Hadis Sects", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="List of hadis sects grouped by type with count", @@ -60,7 +60,7 @@ hadis_category_tree_swagger = swagger_auto_schema( "This sync endpoint returns only category metadata (no hadis payload) for fast offline building of navigation trees. Includes sect information and full category tree with hadis counts and children counts." ), operation_summary="Get Complete Hadis Category Tree", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="Complete hierarchical tree grouped by sect with category metadata including hadis counts and children counts", @@ -168,7 +168,7 @@ hadis_sync_swagger = swagger_auto_schema( operation_description="Get all Hadis data for offline sync. Returns a dictionary keyed by Hadis ID.", operation_summary="Sync Hadis Data", operation_id="syncHadisData", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'last_updated', @@ -308,7 +308,7 @@ hadis_list_swagger = swagger_auto_schema( - `results`: Array of hadis objects with full details """, operation_summary="List Hadis by Category", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'category_slug', @@ -429,7 +429,7 @@ arguments_filters_swagger = swagger_auto_schema( - `results`: Array of hadis objects with full details """, operation_summary="List Hadis by Category", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'Accept-Language', @@ -500,7 +500,7 @@ hadis_basic_swagger = swagger_auto_schema( operation_description="Get basic information about a specific hadis including core text and translation", operation_summary="Get Hadis Basic Info", operation_id="getHadisBasic", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'hadis_slug', @@ -545,7 +545,7 @@ hadis_basic_swagger = swagger_auto_schema( hadis_detail_swagger = swagger_auto_schema( operation_summary="Get Hadis Detail Metadata", operation_description="Retrieve metadata for a specific hadis including Status, Tags, External Links, and Book References. (Note: Text and Narrators are in separate endpoints).", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'hadis_slug', @@ -620,7 +620,7 @@ hadis_transmitters_swagger = swagger_auto_schema( operation_description="Get the chain of transmitters for a specific Hadis. Returns the Hadis ID, the count of unique narrator generations (layers), and the ordered list of transmitters.", operation_summary="Get Hadis Chain (Isnad)", operation_id="getHadisChain", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ # Path Parameter: ID openapi.Parameter( @@ -755,7 +755,7 @@ hadis_corrections_swagger = swagger_auto_schema( """, operation_summary="Get Hadis Corrections", operation_id="getHadisCorrections", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'hadis_slug', @@ -814,7 +814,7 @@ hadis_collections_swagger = swagger_auto_schema( operation_description="Get list of all active hadis collections for browsing and categorization", operation_summary="List Hadis Collections", operation_id="getHadisCollections", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="List of hadis collections", @@ -856,7 +856,7 @@ hadis_info_swagger = swagger_auto_schema( operation_description="Get statistical information about hadis database including counts of categories, references, bookmarks, and narrators", operation_summary="Get Hadis Statistics", operation_id="getHadisInfo", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="Hadis database statistics", @@ -881,7 +881,7 @@ transmitter_list_swagger = swagger_auto_schema( operation_description="Get a paginated list of transmitters (narrators) with optional filtering by reliability, madhhab, and generation.", operation_summary="List Transmitters", operation_id="listTransmitters", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'status', @@ -960,7 +960,7 @@ transmitter_filters_swagger = swagger_auto_schema( operation_description="Get the needed data for filter lists such as madhabs,generations,reliabilities.", operation_summary="Transmitter's List's filters", operation_id="transmiterfilter", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'Accept-Language', @@ -1017,7 +1017,7 @@ transmitter_filters_swagger = swagger_auto_schema( transmitter_detail_swagger = swagger_auto_schema( operation_description="Get detailed information about a specific transmitter including their scholarly opinions and hadith transmissions", operation_summary="Get Transmitter Details", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'narrator_slug', @@ -1073,7 +1073,7 @@ transmitter_sync_swagger = swagger_auto_schema( operation_description="Get complete transmitter (narrator) data for offline synchronization. Returns a flat list of narrators with biographical info.", operation_summary="Sync Transmitter Data", operation_id="syncTransmitterData", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="Complete transmitter data list", @@ -1222,7 +1222,7 @@ transmitter_opinion_swagger = swagger_auto_schema( """, operation_summary="Get Transmitter Opinions", operation_id="getTransmitterOpinions", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'narrator_slug', @@ -1320,7 +1320,7 @@ transmitter_original_text_swagger = swagger_auto_schema( """, operation_summary="Get Transmitter Original Texts", operation_id="getTransmitterOriginalTexts", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'narrator_slug', @@ -1391,7 +1391,7 @@ book_references_list_swagger = swagger_auto_schema( """, operation_summary="List Book References", operation_id="listBookReferences", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'search', @@ -1457,7 +1457,7 @@ reference_sync_swagger = swagger_auto_schema( operation_description="Get complete book reference data for offline synchronization. Returns a paginated list of books with detailed metadata.", operation_summary="Sync Book References Data", operation_id="syncReferenceData", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="Complete book references data list", @@ -1572,7 +1572,7 @@ reference_sync_swagger = swagger_auto_schema( book_authors_list_swagger = swagger_auto_schema( operation_description="Get list of all book authors who have contributed to hadith literature", operation_summary="List Book Authors", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="List of all book authors", @@ -1605,7 +1605,7 @@ book_authors_list_swagger = swagger_auto_schema( book_attributes_list_swagger = swagger_auto_schema( operation_description="Retrieve all custom attributes for books. Optionally filter by book reference ID or attribute title.", operation_summary="List Book Attributes", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'book_reference', @@ -1681,7 +1681,7 @@ book_attributes_list_swagger = swagger_auto_schema( book_attributes_create_swagger = swagger_auto_schema( operation_description="Create a new custom attribute for a book. Attributes can store additional metadata about hadith books such as number of hadith, authenticity grade, or other relevant information.", operation_summary="Create Book Attribute", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['title', 'value', 'book_reference'], @@ -1754,7 +1754,7 @@ book_detail_swagger = swagger_auto_schema( """, operation_summary="Get Book Reference Details", operation_id="getBookReferenceDetails", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'reference_slug', @@ -1866,7 +1866,7 @@ categories_list_swagger = swagger_auto_schema( - `hadis_count`: Total number of hadis in this category """, operation_summary="List All Categories", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description="Successfully retrieved list of all hadith categories", @@ -1940,7 +1940,7 @@ categories_by_sect_swagger = swagger_auto_schema( """, operation_summary="List Categories by Sect", operation_id="listCategoriesBySect", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'sect_type', @@ -2038,7 +2038,7 @@ categories_tree_by_sect_swagger = swagger_auto_schema( """, operation_summary="Get Category Children by Sect and Slug", operation_id="getCategoryChildrenBySectAndSlug", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'sect_type', @@ -2156,7 +2156,7 @@ categories_tree_by_sect_source_swagger = swagger_auto_schema( """, operation_summary="Get Category Children by Sect, Slug and Source", operation_id="getCategoryChildrenBySectSlugAndSource", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'sect_type', @@ -2287,7 +2287,7 @@ hadis_main_list_swagger = swagger_auto_schema( - `results`: Array of hadis objects for the current page with full details including individual status """, operation_summary="List All Hadis with Search & Filters", - tags=['Hadis'], + tags=['Dobodbi - Hadis'], manual_parameters=[ openapi.Parameter( 'search', @@ -2445,7 +2445,7 @@ hadis_main_list_swagger = swagger_auto_schema( content_release_sync_swagger = swagger_auto_schema( operation_description='Get the latest active content release for offline mode sync', operation_summary='Get Latest Content Release', - tags=['Hadis'], + tags=['Dobodbi - Hadis'], responses={ status.HTTP_200_OK: openapi.Response( description='Latest active content release object', diff --git a/apps/library/doc.py b/apps/library/doc.py index 84b62b2..5013d39 100644 --- a/apps/library/doc.py +++ b/apps/library/doc.py @@ -189,7 +189,7 @@ book_detail_swagger = swagger_auto_schema( The book is specified by its ID in the URL path. """, operation_summary="Get Book Detail", - tags=["Library"], + tags=["Dobodbi - Library"], responses={ 200: book_detail_response, 401: "Authentication credentials were not provided or are invalid.", @@ -224,7 +224,7 @@ book_list_swagger = swagger_auto_schema( Note: To get downloaded books, use the separate endpoint /books/downloaded/ """, operation_summary="List Books", - tags=["Library"], + tags=["Dobodbi - Library"], manual_parameters=[collection_id_param, category_param, is_bookmark_param, search_param, sort_param], responses={ 200: books_response, @@ -242,7 +242,7 @@ category_list_swagger = swagger_auto_schema( title, slug, status, books count, and timestamps. """, operation_summary="List Book Categories", - tags=["Library"], + tags=["Dobodbi - Library"], responses={ 200: "List of book categories", 401: "Authentication credentials were not provided or are invalid.", @@ -259,7 +259,7 @@ pinned_collection_list_swagger = swagger_auto_schema( title and the covers of its top books by view count. """, operation_summary="List Pinned Book Collections", - tags=["Library"], + tags=["Dobodbi - Library"], responses={ 200: "List of pinned book collections with covers", 401: "Authentication credentials were not provided or are invalid.", @@ -279,7 +279,7 @@ middle_collection_list_swagger = swagger_auto_schema( view count, download count, and file type. """, operation_summary="List Middle Section Book Collections", - tags=["Library"], + tags=["Dobodbi - Library"], responses={ 200: "List of middle section book collections with their books", 401: "Authentication credentials were not provided or are invalid.", diff --git a/apps/library/views.py b/apps/library/views.py index c069d0c..b7c1c5e 100644 --- a/apps/library/views.py +++ b/apps/library/views.py @@ -223,7 +223,7 @@ class DownloadedBooksListView(ListAPIView): You can search for downloaded books by title, summary, publisher, or ISBN using the 'search' query parameter. """, operation_summary="List Downloaded Books", - tags=["Library"], + tags=["Dobodbi - Library"], manual_parameters=[ openapi.Parameter( 'search', @@ -275,7 +275,7 @@ class BookDownloadCreateAPIView(CreateAPIView): with the current timestamp. """, operation_summary="Download Book", - tags=["Library"], + tags=["Dobodbi - Library"], request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ diff --git a/apps/podcast/views.py b/apps/podcast/views.py index 06d423f..abb87b7 100755 --- a/apps/podcast/views.py +++ b/apps/podcast/views.py @@ -18,6 +18,7 @@ class PodcastCategoryListAPIView(generics.ListAPIView): @swagger_auto_schema( operation_description="Get a list of all active podcast categories", + tags=["Dobodbi - Podcast"], responses={ 200: openapi.Response( description="List of podcast categories", @@ -38,6 +39,18 @@ class PinnedPodcastCollectionListView(generics.ListAPIView): permission_classes = (IsAuthenticated,) pagination_class = NoPagination + @swagger_auto_schema( + operation_description="Get a list of pinned podcast collections", + tags=["Dobodbi - Podcast"], + responses={ + 200: openapi.Response( + description="List of pinned podcast collections", + schema=PinnedPodcastCollectionSerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) def get_queryset(self): return PinnedPodcastCollection.objects.filter( @@ -74,7 +87,20 @@ class MiddlePodcastCollectionListView(generics.ListAPIView): serializer_class = MiddlePodcastCollectionSerializer permission_classes = (IsAuthenticated,) pagination_class = NoPagination - + + @swagger_auto_schema( + operation_description="Get a list of middle podcast collections", + tags=["Dobodbi - Podcast"], + responses={ + 200: openapi.Response( + description="List of middle podcast collections", + schema=MiddlePodcastCollectionSerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return PodcastCollection.objects.filter( status=True, @@ -91,6 +117,7 @@ class PodcastListAPIView(generics.ListAPIView): @swagger_auto_schema( operation_description="Get a list of podcast playlists with optional filtering and sorting", + tags=["Dobodbi - Podcast"], manual_parameters=[ openapi.Parameter( name='category', @@ -195,7 +222,20 @@ class PodcastDetailAPIView(generics.RetrieveAPIView): serializer_class = PodcastPlaylistDetailSerializer lookup_field = 'slug' permission_classes = (IsAuthenticated,) - + + @swagger_auto_schema( + operation_description="Get podcast playlist details by slug", + tags=["Dobodbi - Podcast"], + responses={ + 200: openapi.Response( + description="Podcast playlist details", + schema=PodcastPlaylistDetailSerializer() + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return PodcastPlaylist.objects.filter(status=True) @@ -215,6 +255,7 @@ class UserPlaylistListAPIView(generics.ListAPIView): @swagger_auto_schema( operation_description="Get a list of podcasts in the user's personal playlist", + tags=["Dobodbi - Podcast"], responses={ 200: openapi.Response( description="List of podcasts in the user's playlist", @@ -247,6 +288,7 @@ class UserPlaylistCreateAPIView(generics.CreateAPIView): @swagger_auto_schema( operation_description="Add or update a podcast in the user's personal playlist", + tags=["Dobodbi - Podcast"], request_body=UserPlaylistCreateSerializer, responses={ 201: openapi.Response( diff --git a/apps/quiz/views/participant.py b/apps/quiz/views/participant.py index 2a0504d..32ab5fa 100644 --- a/apps/quiz/views/participant.py +++ b/apps/quiz/views/participant.py @@ -17,6 +17,7 @@ class QuizParticipantCreateAPIView(CreateAPIView): @swagger_auto_schema( operation_description=doc_quiz_submit(), + tags=["Imam-Javad - Quiz"], ) def post(self, request, *args, **kwargs): return super().post(request, *args, **kwargs) diff --git a/apps/quiz/views/quiz.py b/apps/quiz/views/quiz.py index 0f42c90..9abb26d 100644 --- a/apps/quiz/views/quiz.py +++ b/apps/quiz/views/quiz.py @@ -17,6 +17,7 @@ class QuizDetailAPIView(RetrieveAPIView): @swagger_auto_schema( operation_description=doc_quiz_detail(), + tags=["Imam-Javad - Quiz"], ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) diff --git a/apps/transaction/views.py b/apps/transaction/views.py index 06f377a..e8df130 100644 --- a/apps/transaction/views.py +++ b/apps/transaction/views.py @@ -105,7 +105,7 @@ class TransactionParticipantCreateView(generics.CreateAPIView): ) ), }, - tags=['transaction'] + tags=['Imam-Javad - Transaction'] ) def post(self, request, *args, **kwargs): # Simply call the create method @@ -210,8 +210,11 @@ class TransactiontListView(generics.ListAPIView): permission_classes = [IsAuthenticated] @swagger_auto_schema( - operation_description=doc_transaction_list() + operation_description=doc_transaction_list(), + tags=['Imam-Javad - Transaction'] ) + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) def get_queryset(self): queryset = super().get_queryset() queryset = queryset.filter(user=self.request.user, is_deleted=False) @@ -225,6 +228,7 @@ class SoftDeleteTransactionParticipantView(APIView): @swagger_auto_schema( operation_summary="Soft delete a transaction participant", operation_description="Marks a transaction participant as deleted without removing it from the database", + tags=['Imam-Javad - Transaction'], manual_parameters=[ openapi.Parameter( 'id', @@ -274,6 +278,7 @@ class UploadTransactionReceiptsView(APIView): @swagger_auto_schema( operation_summary="Upload payment receipts for a transaction", operation_description=doc_upload_transaction_receipts(), + tags=['Imam-Javad - Transaction'], request_body=UploadReceiptsSerializer, responses={ 201: openapi.Response( @@ -361,6 +366,7 @@ class TransactionReceiptsListView(generics.ListAPIView): @swagger_auto_schema( operation_summary="List receipts for a transaction", operation_description=doc_list_transaction_receipts(), + tags=['Imam-Javad - Transaction'], manual_parameters=[ openapi.Parameter( 'transaction_id', @@ -376,6 +382,9 @@ class TransactionReceiptsListView(generics.ListAPIView): 404: "Transaction not found" } ) + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + def get_queryset(self): transaction_id = self.kwargs.get('transaction_id') diff --git a/apps/video/views.py b/apps/video/views.py index c8d3d69..a63a493 100755 --- a/apps/video/views.py +++ b/apps/video/views.py @@ -18,6 +18,7 @@ class VideoCategoryListAPIView(generics.ListAPIView): @swagger_auto_schema( operation_description="Get a list of all active video categories", + tags=["Dobodbi - Video"], responses={ 200: openapi.Response( description="List of video categories", @@ -43,6 +44,18 @@ class PinnedVideoCollectionListView(generics.ListAPIView): permission_classes = (IsAuthenticated,) pagination_class = NoPagination + @swagger_auto_schema( + operation_description="Get a list of pinned video collections", + tags=["Dobodbi - Video"], + responses={ + 200: openapi.Response( + description="List of pinned video collections", + schema=PinnedVideoCollectionSerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) def get_queryset(self): return PinnedVideoCollection.objects.filter( @@ -75,7 +88,20 @@ class MiddleVideoCollectionListView(generics.ListAPIView): serializer_class = MiddleVideoCollectionSerializer permission_classes = (IsAuthenticated,) pagination_class = NoPagination - + + @swagger_auto_schema( + operation_description="Get a list of middle video collections", + tags=["Dobodbi - Video"], + responses={ + 200: openapi.Response( + description="List of middle video collections", + schema=MiddleVideoCollectionSerializer(many=True) + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return VideoCollection.objects.filter( status=True, @@ -92,6 +118,7 @@ class VideoPlaylistListAPIView(generics.ListAPIView): @swagger_auto_schema( operation_description="Get a list of video playlists with optional filtering", + tags=["Dobodbi - Video"], manual_parameters=[ openapi.Parameter( name='category', @@ -187,7 +214,20 @@ class VideoPlaylistDetailAPIView(generics.RetrieveAPIView): serializer_class = VideoPlaylistDetailSerializer permission_classes = (IsAuthenticated,) lookup_field = 'slug' - + + @swagger_auto_schema( + operation_description="Get video playlist details by slug", + tags=["Dobodbi - Video"], + responses={ + 200: openapi.Response( + description="Video playlist details", + schema=VideoPlaylistDetailSerializer() + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return VideoPlaylist.objects.filter(status=True) @@ -202,7 +242,20 @@ class VideoDetailAPIView(generics.RetrieveAPIView): serializer_class = VideoDetailSerializer permission_classes = (IsAuthenticated,) lookup_field = 'slug' - + + @swagger_auto_schema( + operation_description="Get video details by slug", + tags=["Dobodbi - Video"], + responses={ + 200: openapi.Response( + description="Video details", + schema=VideoDetailSerializer() + ) + } + ) + def get(self, request, *args, **kwargs): + return super().get(request, *args, **kwargs) + def get_queryset(self): return Video.objects.filter(status=True)