import json from django.shortcuts import render from django.views import View from django.contrib.admin.views.decorators import staff_member_required from django.utils.decorators import method_decorator @method_decorator(staff_member_required, name='dispatch') class CustomAPIDocumentationView(View): """ Custom API Documentation view with collapsible sidebar navigation Requires admin login to access """ def get(self, request): api_structure = self._get_api_structure() context = { 'api_structure': api_structure, 'request': request, 'title': 'Imam Javad API Documentation', 'description': 'Comprehensive API documentation with interactive examples for the Imam Javad project', } return render(request, 'api/documentation.html', context) def _get_api_structure(self): """ Define the API structure for the Imam Javad project with all apps and endpoints """ return { 'account': { 'name': 'Account Management', 'description': 'User authentication, registration, and profile management', 'endpoints': [ { 'name': 'User Registration', 'method': 'POST', 'url': '/api/account/register/', 'description': 'Register a new user account with email verification', 'parameters': [ {'name': 'email', 'type': 'string', 'description': 'User email address', 'required': True}, {'name': 'password', 'type': 'string', 'description': 'User password', 'required': True}, {'name': 'password_confirm', 'type': 'string', 'description': 'Password confirmation', 'required': True}, {'name': 'fullname', 'type': 'string', 'description': 'User full name', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "message": "Registration successful. Please check your email for verification code.", "user_id": 123, "email": "user@example.com" }, indent=2), 'error': json.dumps({ "error": "Email already exists", "details": "A user with this email address already exists." }, indent=2) } }, { 'name': 'Email Verification', 'method': 'POST', 'url': '/api/account/verify/', 'description': 'Verify user email with verification code', 'parameters': [ {'name': 'email', 'type': 'string', 'description': 'User email address', 'required': True}, {'name': 'code', 'type': 'string', 'description': 'Verification code from email', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "message": "Email verified successfully", "token": "abc123def456...", "user": { "id": 123, "email": "user@example.com", "fullname": "John Doe", "is_verified": True } }, indent=2) } }, { 'name': 'User Login', 'method': 'POST', 'url': '/api/account/login/', 'description': 'Authenticate user and get access token', 'parameters': [ {'name': 'email', 'type': 'string', 'description': 'User email address', 'required': True}, {'name': 'password', 'type': 'string', 'description': 'User password', 'required': True}, {'name': 'fcm', 'type': 'string', 'description': 'FCM token for notifications', 'required': False}, {'name': 'device_id', 'type': 'string', 'description': 'Device identifier', 'required': False}, ], 'response_examples': { 'success': json.dumps({ "token": "abc123def456...", "user": { "id": 123, "email": "user@example.com", "fullname": "John Doe", "is_verified": True, "profile_image": None } }, indent=2) } }, { 'name': 'User Profile', 'method': 'GET', 'url': '/api/account/profile/', 'description': 'Get current user profile information', 'parameters': [ {'name': 'Authorization', 'type': 'header', 'description': 'Token ', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "id": 123, "email": "user@example.com", "fullname": "John Doe", "phone": "+989123456789", "profile_image": "https://example.com/media/profiles/user.jpg", "is_verified": True, "date_joined": "2024-01-15T10:30:00Z" }, indent=2) } } ] }, 'courses': { 'name': 'Course Management', 'description': 'Educational courses, lessons, and learning progress', 'endpoints': [ { 'name': 'Course Categories', 'method': 'GET', 'url': '/api/courses/categories/', 'description': 'Get list of all course categories', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 5, "results": [ { "id": 1, "title": "Islamic Studies", "description": "Courses related to Islamic knowledge", "image": "https://example.com/media/categories/islamic.jpg", "courses_count": 12 }, { "id": 2, "title": "Arabic Language", "description": "Arabic language learning courses", "image": "https://example.com/media/categories/arabic.jpg", "courses_count": 8 } ] }, indent=2) } }, { 'name': 'Course List', 'method': 'GET', 'url': '/api/courses/', 'description': 'Get paginated list of courses with filtering options', 'parameters': [ {'name': 'category', 'type': 'integer', 'description': 'Filter by category ID', 'required': False}, {'name': 'search', 'type': 'string', 'description': 'Search in course titles', 'required': False}, {'name': 'page', 'type': 'integer', 'description': 'Page number for pagination', 'required': False}, ], 'response_examples': { 'success': json.dumps({ "count": 25, "next": "http://example.com/api/courses/?page=2", "previous": None, "results": [ { "id": 1, "title": "Introduction to Islamic Jurisprudence", "slug": "intro-islamic-jurisprudence", "category": { "id": 1, "title": "Islamic Studies" }, "professor": { "id": 1, "name": "Dr. Ahmad Hassan", "bio": "Expert in Islamic Law" }, "thumbnail": "https://example.com/media/courses/course1.jpg", "duration": "8 weeks", "lessons_count": 24, "participants_count": 156, "price": "50.00", "is_free": False } ] }, indent=2) } } ] }, 'hadis': { 'name': 'Hadis Collection', 'description': 'Islamic hadis texts organized by categories and sects', 'endpoints': [ { 'name': 'Hadis Sects', 'method': 'GET', 'url': '/api/hadis/categories/', 'description': 'Get list of hadis sects grouped by type (Shia/Sunni)', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 4, "results": { "shia": [ { "id": 1, "title": "Twelver Shia", "seo_field": None } ], "sunni": [ { "id": 3, "title": "Hanafi", "seo_field": None } ] } }, indent=2) } }, { 'name': 'Hadis Categories', 'method': 'GET', 'url': '/api/hadis/categories//', 'description': 'Get hadis categories tree structure by sect ID', 'parameters': [ {'name': 'sect_id', 'type': 'integer', 'description': 'Hadis sect ID', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "count": 10, "results": { "quran": [ { "id": 1, "title": "Quranic Interpretations", "order": 1, "children": [ { "id": 2, "title": "Tafsir al-Mizan", "order": 1, "hadis_count": 45 } ] } ], "hadith": [ { "id": 10, "title": "Prophetic Traditions", "order": 1, "children": [] } ] } }, indent=2) } } ] }, 'library': { 'name': 'Digital Library', 'description': 'Books, documents, and downloadable resources', 'endpoints': [ { 'name': 'Book Categories', 'method': 'GET', 'url': '/api/library/categories/', 'description': 'Get list of book categories', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 8, "results": [ { "id": 1, "title": "Islamic Jurisprudence", "description": "Books on Islamic law and jurisprudence", "books_count": 45 } ] }, indent=2) } }, { 'name': 'Book List', 'method': 'GET', 'url': '/api/library/books/', 'description': 'Get paginated list of books', 'parameters': [ {'name': 'category', 'type': 'integer', 'description': 'Filter by category ID', 'required': False}, {'name': 'search', 'type': 'string', 'description': 'Search in book titles and authors', 'required': False}, ], 'response_examples': { 'success': json.dumps({ "count": 120, "results": [ { "id": 1, "title": "Al-Kafi", "author": "Muhammad ibn Ya'qub al-Kulayni", "description": "One of the most important Shia hadith collections", "cover_image": "https://example.com/media/books/alkafi.jpg", "file_size": "15.2 MB", "pages": 1200, "language": "Arabic", "download_count": 2456 } ] }, indent=2) } } ] }, 'videos': { 'name': 'Video Playlists', 'description': 'Educational and religious video playlist collections', 'endpoints': [ { 'name': 'Video Categories', 'method': 'GET', 'url': '/api/videos/categories/', 'description': 'Get list of video categories', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 6, "results": [ { "id": 1, "title": "Lectures", "slug": "lectures", "playlist_count": 23 } ] }, indent=2) } }, { 'name': 'Pinned Collections', 'method': 'GET', 'url': '/api/videos/pinned-collections/', 'description': 'Get pinned video playlist collections', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 3, "info": { "categories_count": 6, "bookmarks_count": 45 }, "results": [ { "id": 1, "title": "Featured Videos", "slug": "featured-videos", "summary": "Our best video content", "thumbnail": "https://example.com/media/collections/thumb1.jpg", "order": 1, "created_at": "2024-01-15T10:30:00Z" } ] }, indent=2) } }, { 'name': 'Video Collections', 'method': 'GET', 'url': '/api/videos/collections/', 'description': 'Get video collections with playlists', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 8, "results": [ { "id": 1, "title": "Islamic Philosophy Series", "slug": "islamic-philosophy", "summary": "Complete series on Islamic philosophy", "playlists": [ { "id": 1, "title": "Introduction to Islamic Philosophy", "slug": "intro-islamic-philosophy", "thumbnail": "https://example.com/media/playlists/thumb1.jpg", "slogan": "Learn the basics of Islamic thought", "view_count": 1234, "total_time_formatted": "02:45:30", "order": 1, "created_at": "2024-01-15T10:30:00Z" } ] } ] }, indent=2) } }, { 'name': 'Video Playlist List', 'method': 'GET', 'url': '/api/videos/playlists/', 'description': 'Get paginated list of video playlists', 'parameters': [ {'name': 'category', 'type': 'string', 'description': 'Filter by category slug', 'required': False}, {'name': 'collection', 'type': 'string', 'description': 'Filter by collection slug', 'required': False}, {'name': 'is_bookmark', 'type': 'boolean', 'description': 'Filter bookmarked playlists', 'required': False}, {'name': 'search', 'type': 'string', 'description': 'Search in playlist titles', 'required': False}, ], 'response_examples': { 'success': json.dumps({ "count": 45, "results": [ { "id": 1, "title": "Introduction to Islamic Philosophy", "slug": "intro-islamic-philosophy", "thumbnail": "https://example.com/media/playlists/thumb1.jpg", "slogan": "Learn the basics of Islamic thought", "view_count": 1234, "total_time_formatted": "02:45:30", "order": 1, "created_at": "2024-01-15T10:30:00Z" } ] }, indent=2) } }, { 'name': 'Video Playlist Detail', 'method': 'GET', 'url': '/api/videos/playlists//', 'description': 'Get detailed information about a video playlist', 'parameters': [ {'name': 'slug', 'type': 'string', 'description': 'Playlist slug', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "id": 1, "title": "Introduction to Islamic Philosophy", "slug": "intro-islamic-philosophy", "thumbnail": "https://example.com/media/playlists/thumb1.jpg", "slogan": "Learn the basics of Islamic thought", "description": "A comprehensive introduction to Islamic philosophical concepts", "view_count": 1234, "total_time_formatted": "02:45:30", "order": 1, "status": True, "categories": [ { "id": 1, "title": "Philosophy", "slug": "philosophy", "playlist_count": 12 } ], "user_rate": { "is_rated": True, "rate": 5 }, "average_rate": 4.5, "bookmark": True, "videos": [ { "id": 1, "title": "Chapter 1: Introduction", "slug": "chapter-1-intro", "thumbnail": "https://example.com/media/videos/thumb1.jpg", "description": "First chapter introduction", "video_time": "00:45:30", "view_count": 567, "created_at": "2024-01-15T10:30:00Z" } ], "created_at": "2024-01-15T10:30:00Z" }, indent=2) } } ] }, 'podcast': { 'name': 'Podcast Platform', 'description': 'Audio content organized in playlists', 'endpoints': [ { 'name': 'Podcast Categories', 'method': 'GET', 'url': '/api/podcast/categories/', 'description': 'Get list of podcast categories', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 4, "results": [ { "id": 1, "title": "Religious Discussions", "slug": "religious-discussions", "playlist_count": 23 } ] }, indent=2) } }, { 'name': 'Pinned Collections', 'method': 'GET', 'url': '/api/podcast/pinned-collections/', 'description': 'Get pinned podcast playlist collections', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 3, "info": { "categories_count": 6, "bookmarks_count": 45 }, "results": [ { "id": 1, "title": "Featured Podcasts", "slug": "featured-podcasts", "summary": "Our best podcast content", "thumbnail": "https://example.com/media/collections/thumb1.jpg", "order": 1, "created_at": "2024-01-15T10:30:00Z" } ] }, indent=2) } }, { 'name': 'Podcast Collections', 'method': 'GET', 'url': '/api/podcast/collections/', 'description': 'Get podcast collections with playlists', 'parameters': [], 'response_examples': { 'success': json.dumps({ "count": 8, "results": [ { "id": 1, "title": "Islamic Philosophy Audio Series", "slug": "islamic-philosophy-audio", "summary": "Complete audio series on Islamic philosophy", "playlists": [ { "id": 1, "title": "Introduction to Islamic Philosophy - Audio", "slug": "intro-islamic-philosophy-audio", "thumbnail": "https://example.com/media/playlists/thumb1.jpg", "slogan": "Learn the basics of Islamic thought through audio", "view_count": 1234, "total_time_formatted": "02:45:30", "order": 1, "created_at": "2024-01-15T10:30:00Z" } ] } ] }, indent=2) } }, { 'name': 'Podcast Playlist List', 'method': 'GET', 'url': '/api/podcast/playlists/', 'description': 'Get paginated list of podcast playlists', 'parameters': [ {'name': 'category', 'type': 'string', 'description': 'Filter by category slug', 'required': False}, {'name': 'collection', 'type': 'string', 'description': 'Filter by collection slug', 'required': False}, {'name': 'is_bookmark', 'type': 'boolean', 'description': 'Filter bookmarked playlists', 'required': False}, {'name': 'search', 'type': 'string', 'description': 'Search in playlist titles', 'required': False}, ], 'response_examples': { 'success': json.dumps({ "count": 45, "results": [ { "id": 1, "title": "Introduction to Islamic Philosophy - Audio", "slug": "intro-islamic-philosophy-audio", "thumbnail": "https://example.com/media/playlists/thumb1.jpg", "slogan": "Learn the basics of Islamic thought through audio", "view_count": 1234, "total_time_formatted": "02:45:30", "order": 1, "created_at": "2024-01-15T10:30:00Z" } ] }, indent=2) } }, { 'name': 'Podcast Playlist Detail', 'method': 'GET', 'url': '/api/podcast/playlists//', 'description': 'Get detailed information about a podcast playlist', 'parameters': [ {'name': 'slug', 'type': 'string', 'description': 'Playlist slug', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "id": 1, "title": "Introduction to Islamic Philosophy - Audio", "slug": "intro-islamic-philosophy-audio", "thumbnail": "https://example.com/media/playlists/thumb1.jpg", "slogan": "Learn the basics of Islamic thought through audio", "description": "A comprehensive audio introduction to Islamic philosophical concepts", "view_count": 1234, "total_time_formatted": "02:45:30", "order": 1, "status": True, "categories": [ { "id": 1, "title": "Philosophy", "slug": "philosophy", "playlist_count": 12 } ], "user_rate": { "is_rated": True, "rate": 5 }, "average_rate": 4.5, "bookmark": True, "podcasts": [ { "id": 1, "title": "Episode 1: Introduction", "slug": "episode-1-intro", "thumbnail": "https://example.com/media/podcasts/thumb1.jpg", "description": "First episode introduction", "audio_time": "00:45:30", "view_count": 567, "created_at": "2024-01-15T10:30:00Z", "in_user_playlist": False } ], "created_at": "2024-01-15T10:30:00Z" }, indent=2) } } ] }, 'quiz': { 'name': 'Quiz System', 'description': 'Interactive quizzes and assessments', 'endpoints': [ { 'name': 'Quiz Detail', 'method': 'GET', 'url': '/api/quiz//', 'description': 'Get quiz details and questions', 'parameters': [ {'name': 'quiz_id', 'type': 'integer', 'description': 'Quiz ID', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "id": 1, "title": "Islamic History Quiz", "description": "Test your knowledge of Islamic history", "each_question_timing": 30, "questions": [ { "id": 1, "question": "When was the Battle of Badr fought?", "options": [ {"id": 1, "text": "624 CE"}, {"id": 2, "text": "625 CE"}, {"id": 3, "text": "626 CE"}, {"id": 4, "text": "627 CE"} ] } ] }, indent=2) } } ] }, 'bookmarks': { 'name': 'Bookmarks & Ratings', 'description': 'User bookmarks and content ratings', 'endpoints': [ { 'name': 'Add Bookmark', 'method': 'POST', 'url': '/api/bookmarks/add/', 'description': 'Add content to user bookmarks', 'parameters': [ {'name': 'content_type', 'type': 'string', 'description': 'Type of content (course, video, etc.)', 'required': True}, {'name': 'object_id', 'type': 'integer', 'description': 'ID of the content object', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "message": "Bookmark added successfully", "bookmark_id": 123 }, indent=2) } } ] }, 'api': { 'name': 'General API', 'description': 'General endpoints (health, countries, comments, app versions)', 'endpoints': [ { 'name': 'Health / Token Test', 'method': 'GET', 'url': '/api/test/', 'description': 'Health check; echoes optional BUILD_NUMBER header', 'parameters': [ {'name': 'BUILD_NUMBER', 'type': 'header', 'description': 'Client build number', 'required': False}, ], 'response_examples': { 'success': json.dumps({ "token": "ok", "build_number": "1.0.0(100)" }, indent=2) } }, { 'name': 'Countries', 'method': 'GET', 'url': '/api/test/countries/', 'description': 'List of countries with dialing codes and flags', 'parameters': [], 'response_examples': { 'success': json.dumps([ {"name": "Iran", "dial_code": "+98", "code": "IR"} ], indent=2) } }, { 'name': 'Comments', 'method': 'GET', 'url': '/api/test/comments/', 'description': 'List comments ordered by order and created_at', 'parameters': [], 'response_examples': { 'success': json.dumps([ {"id": 1, "user_fullname": "Ali Reza", "comment_text": "Great app!"} ], indent=2) } }, { 'name': 'App Versions', 'method': 'GET', 'url': '/api/test/app-versions/', 'description': 'List all app versions', 'parameters': [], 'response_examples': { 'success': json.dumps([ { "id": 3, "version": "1.2.0", "apk_file": "https://host/media/app_versions/app-release.apk", "description": "Bug fixes", "app_type": "google_play", "app_store_downloads": 1500, "google_play_downloads": 23000, "is_active": True } ], indent=2) } } ] }, 'blog': { 'name': 'Blog', 'description': 'Blog posts listing and details', 'endpoints': [ { 'name': 'Blog List', 'method': 'GET', 'url': '/api/blog/list/', 'description': 'List blogs with optional search and sort_by', 'parameters': [ {'name': 'search', 'type': 'string', 'description': 'Search in title, slogan, or summary', 'required': False}, {'name': 'sort_by', 'type': 'string', 'description': "Sorting: 'latest' or 'most_viewed'", 'required': False}, ], 'response_examples': { 'success': json.dumps({ "count": 1, "results": [ {"id": 1, "title": "First blog", "views_count": 10} ] }, indent=2) } }, { 'name': 'Related Blogs', 'method': 'GET', 'url': '/api/blog/related//', 'description': 'Get up to 10 random related blogs excluding current', 'parameters': [ {'name': 'blog_id', 'type': 'integer', 'description': 'Current blog ID', 'required': True}, ], 'response_examples': { 'success': json.dumps([ {"id": 2, "title": "Another blog"} ], indent=2) } }, { 'name': 'Blog Detail by Slug', 'method': 'GET', 'url': '/api/blog/detail//', 'description': 'Get blog details by slug; increments view count', 'parameters': [ {'name': 'slug', 'type': 'string', 'description': 'Blog slug', 'required': True}, ], 'response_examples': { 'success': json.dumps({ "id": 1, "title": "First blog", "views_count": 11 }, indent=2) } } ] } }