From c7d46c9833d3289fc8e5c1c7ce8f884452da859d Mon Sep 17 00:00:00 2001 From: mortezaei Date: Mon, 1 Dec 2025 14:20:30 +0330 Subject: [PATCH] feat(podcast, video): implement category creation and playlist association for podcasts and videos - Added management commands to create podcast and video categories in Russian, ensuring a structured categorization system. - Updated podcast and video playlist creation commands to associate playlists with the newly created categories. - Enhanced documentation to reflect the new category creation process and its integration into the podcast and video systems. --- PODCAST_SETUP_GUIDE.md | 57 ++++++++++-- VIDEO_REFACTORING_SUMMARY.md | 26 ++++-- .../commands/create_podcast_categories.py | 88 +++++++++++++++++++ .../commands/create_podcast_playlists.py | 40 ++++++--- .../commands/create_video_categories.py | 88 +++++++++++++++++++ .../commands/create_video_playlists.py | 40 ++++++--- 6 files changed, 305 insertions(+), 34 deletions(-) create mode 100644 apps/podcast/management/commands/create_podcast_categories.py create mode 100644 apps/video/management/commands/create_video_categories.py diff --git a/PODCAST_SETUP_GUIDE.md b/PODCAST_SETUP_GUIDE.md index 3c08c89..8b0bdff 100644 --- a/PODCAST_SETUP_GUIDE.md +++ b/PODCAST_SETUP_GUIDE.md @@ -54,7 +54,46 @@ PlaylistItem: 12 --- -### 3️⃣ تبدیل ویدیوها به پادکست +### 3️⃣ ایجاد دسته‌بندی‌های پادکست + +ابتدا باید 8 دسته‌بندی برای پادکست‌ها ایجاد کنید: + +```bash +python manage.py create_podcast_categories +``` + +**این دستور چه کاری انجام می‌دهد:** +- ✅ 8 دسته‌بندی با عناوین روسی ایجاد می‌کند +- ✅ ترتیب (order) برای هر دسته تعیین می‌کند +- ✅ همه را فعال (status=True) می‌کند + +**دسته‌بندی‌های ایجاد شده:** +1. Пророки и посланники (پیامبران و فرستادگان) +2. Имамы Ахль аль-Байт (امامان اهل‌بیت) +3. Коранические истории (داستان‌های قرآنی) +4. Исламская философия (فلسفه اسلامی) +5. Нравственность и этика (اخلاق و آداب) +6. История ислама (تاریخ اسلام) +7. Кербела и Ашура (کربلا و عاشورا) +8. Духовное развитие (رشد معنوی) + +**خروجی نمونه:** +``` +✓ Created category: Пророки и посланники +✓ Created category: Имамы Ахль аль-Байт +... +✓ Successfully created 8 categories! +``` + +**گزینه‌های اضافی:** +```bash +# پاک کردن دسته‌بندی‌های قبلی و ایجاد مجدد +python manage.py create_podcast_categories --clean +``` + +--- + +### 4️⃣ تبدیل ویدیوها به پادکست این مرحله **مهم‌ترین مرحله** است. ویدیوها را به پادکست (صدا) تبدیل می‌کند: @@ -117,7 +156,7 @@ Processing: Истории пророков в Коране --- -### 4️⃣ ایجاد 10 پلی‌لیست پادکست +### 5️⃣ ایجاد 10 پلی‌لیست پادکست حالا پادکست‌ها را در 10 پلی‌لیست سازماندهی می‌کنیم: @@ -171,7 +210,7 @@ python manage.py create_podcast_playlists --dry-run --- -### 5️⃣ بررسی نتیجه نهایی +### 6️⃣ بررسی نتیجه نهایی برای اطمینان از موفقیت‌آمیز بودن تمام مراحل: @@ -237,16 +276,20 @@ python manage.py migrate podcast # 2. پاکسازی داده‌های قدیمی (اختیاری) python manage.py cleanup_podcast_data --confirm -# 3. تبدیل ویدیوها به پادکست (مهم!) +# 3. ایجاد دسته‌بندی‌ها (8 category) +python manage.py create_podcast_categories + +# 4. تبدیل ویدیوها به پادکست (مهم!) python manage.py convert_videos_to_podcasts -# 4. ایجاد پلی‌لیست‌ها +# 5. ایجاد پلی‌لیست‌ها (با اتصال به categories) python manage.py create_podcast_playlists -# 5. بررسی نتیجه +# 6. بررسی نتیجه python manage.py shell -c " -from apps.podcast.models import Podcast, PodcastPlaylist +from apps.podcast.models import Podcast, PodcastPlaylist, PodcastCategory print(f'Podcasts: {Podcast.objects.count()}') +print(f'Categories: {PodcastCategory.objects.count()}') print(f'Playlists: {PodcastPlaylist.objects.count()}') " ``` diff --git a/VIDEO_REFACTORING_SUMMARY.md b/VIDEO_REFACTORING_SUMMARY.md index afdc86e..976b4ab 100644 --- a/VIDEO_REFACTORING_SUMMARY.md +++ b/VIDEO_REFACTORING_SUMMARY.md @@ -120,25 +120,41 @@ python manage.py create_video_playlists --dry-run # for testing 5. 🔄 Create new VideoCategories and assign to playlists (if needed) 6. 🔄 Test all API endpoints -## Commands for Future Use +## Commands for Setup (in order) ```bash -# Clean up all playlist/collection/category data (keeps videos) +# 1. Apply migration (already done) +python manage.py migrate video + +# 2. Clean up old data (if needed) python manage.py cleanup_video_data --confirm -# Create 10 playlists with all videos +# 3. Create 8 video categories +python manage.py create_video_categories + +# 4. Create 10 playlists with all videos (automatically connects to categories) python manage.py create_video_playlists -# Check current state +# 5. Check current state python manage.py shell -c " from apps.video.models import Video, VideoPlaylist, VideoCollection, VideoCategory print(f'Videos: {Video.objects.count()}') +print(f'Categories: {VideoCategory.objects.count()}') print(f'Playlists: {VideoPlaylist.objects.count()}') print(f'Collections: {VideoCollection.objects.count()}') -print(f'Categories: {VideoCategory.objects.count()}') " ``` +### Video Categories Created: +1. Пророки и посланники (Prophets and Messengers) +2. Имамы Ахль аль-Байт (Imams of Ahl al-Bayt) +3. Коранические истории (Quranic Stories) +4. Исламская философия (Islamic Philosophy) +5. Нравственность и этика (Morality and Ethics) +6. История ислама (History of Islam) +7. Кербела и Ашура (Karbala and Ashura) +8. Духовное развитие (Spiritual Development) + ## Important Notes - ⚠️ VideoInCollection model is completely removed - old code referencing it will break diff --git a/apps/podcast/management/commands/create_podcast_categories.py b/apps/podcast/management/commands/create_podcast_categories.py new file mode 100644 index 0000000..1993560 --- /dev/null +++ b/apps/podcast/management/commands/create_podcast_categories.py @@ -0,0 +1,88 @@ +from django.core.management.base import BaseCommand +from django.db import transaction +from apps.podcast.models import PodcastCategory + + +class Command(BaseCommand): + help = 'Create podcast categories in Russian language' + + # Russian podcast categories + CATEGORIES_DATA = [ + { + 'title': 'Пророки и посланники', + 'order': 10 + }, + { + 'title': 'Имамы Ахль аль-Байт', + 'order': 20 + }, + { + 'title': 'Коранические истории', + 'order': 30 + }, + { + 'title': 'Исламская философия', + 'order': 40 + }, + { + 'title': 'Нравственность и этика', + 'order': 50 + }, + { + 'title': 'История ислама', + 'order': 60 + }, + { + 'title': 'Кербела и Ашура', + 'order': 70 + }, + { + 'title': 'Духовное развитие', + 'order': 80 + } + ] + + def add_arguments(self, parser): + parser.add_argument( + '--clean', + action='store_true', + help='Delete existing categories before creating new ones' + ) + + def handle(self, *args, **options): + clean = options.get('clean', False) + + if clean: + deleted_count = PodcastCategory.objects.count() + PodcastCategory.objects.all().delete() + self.stdout.write(self.style.WARNING(f'Deleted {deleted_count} existing categories')) + + try: + with transaction.atomic(): + created_categories = [] + + for category_data in self.CATEGORIES_DATA: + # Check if category already exists + title = category_data['title'] + category, created = PodcastCategory.objects.get_or_create( + title=title, + defaults={ + 'order': category_data['order'], + 'status': True + } + ) + + if created: + self.stdout.write(self.style.SUCCESS(f'✓ Created category: {category.title}')) + created_categories.append(category) + else: + self.stdout.write(self.style.WARNING(f'⚠ Category already exists: {category.title}')) + + if created_categories: + self.stdout.write(self.style.SUCCESS(f'\n✓ Successfully created {len(created_categories)} categories!')) + else: + self.stdout.write(self.style.WARNING('\nNo new categories created (all already exist)')) + + except Exception as e: + self.stdout.write(self.style.ERROR(f'\n✗ Error during creation: {str(e)}')) + raise diff --git a/apps/podcast/management/commands/create_podcast_playlists.py b/apps/podcast/management/commands/create_podcast_playlists.py index e6cfe16..ddb36d3 100644 --- a/apps/podcast/management/commands/create_podcast_playlists.py +++ b/apps/podcast/management/commands/create_podcast_playlists.py @@ -1,63 +1,74 @@ import random from django.core.management.base import BaseCommand from django.db import transaction -from apps.podcast.models import Podcast, PodcastPlaylist, PlaylistItem +from apps.podcast.models import Podcast, PodcastPlaylist, PlaylistItem, PodcastCategory class Command(BaseCommand): help = 'Create 10 podcast playlists in Russian language about prophets and imams, and add all podcasts to each playlist' # Russian playlist data about prophets and imams + # Each playlist has associated category titles PLAYLISTS_DATA = [ { 'title': 'Лекции о Пророке Мухаммаде (да благословит его Аллах)', 'slogan': 'Аудио лекции о жизни последнего пророка', - 'description': 'Полная коллекция аудио лекций о жизни, учениях и наследии Пророка Мухаммада (мир ему и благословение Аллаха). Узнайте о его миссии, характере и влиянии на человечество.' + 'description': 'Полная коллекция аудио лекций о жизни, учениях и наследии Пророка Мухаммада (мир ему и благословение Аллаха). Узнайте о его миссии, характере и влиянии на человечество.', + 'categories': ['Пророки и посланники', 'История ислама'] }, { 'title': 'Истории пророков в аудио формате', 'slogan': 'Повествования о посланниках Аллаха', - 'description': 'Глубокое изучение историй пророков, упомянутых в Священном Коране. От Адама до Мухаммада (мир им всем), узнайте об их испытаниях, учениях и вере в аудио лекциях.' + 'description': 'Глубокое изучение историй пророков, упомянутых в Священном Коране. От Адама до Мухаммада (мир им всем), узнайте об их испытаниях, учениях и вере в аудио лекциях.', + 'categories': ['Пророки и посланники', 'Коранические истории'] }, { 'title': 'Имам Али: Аудио наставления', 'slogan': 'Мудрость первого Имама в аудио', - 'description': 'Исследование жизни, учений и мудрости Имама Али ибн Аби Талиба через аудио лекции. Его речи, письма и руководство для верующих.' + 'description': 'Исследование жизни, учений и мудрости Имама Али ибн Аби Талиба через аудио лекции. Его речи, письма и руководство для верующих.', + 'categories': ['Имамы Ахль аль-Байт', 'Исламская философия'] }, { 'title': 'Имам Хусейн: Аудио о Кербеле', 'slogan': 'Подкасты о жертве ради истины', - 'description': 'Полное понимание событий Ашуры и мученичества Имама Хусейна через аудио материалы. Узнайте о его стойкости против угнетения.' + 'description': 'Полное понимание событий Ашуры и мученичества Имама Хусейна через аудио материалы. Узнайте о его стойкости против угнетения.', + 'categories': ['Имамы Ахль аль-Байт', 'Кербела и Ашура', 'История ислама'] }, { 'title': 'Двенадцать Имамов: Аудио курс', 'slogan': 'Светильники руководства в аудио', - 'description': 'Всестороннее изучение жизни и учений двенадцати непогрешимых Имамов из рода Пророка. Их роль в сохранении истинного ислама в аудио лекциях.' + 'description': 'Всестороннее изучение жизни и учений двенадцати непогрешимых Имамов из рода Пророка. Их роль в сохранении истинного ислама в аудио лекциях.', + 'categories': ['Имамы Ахль аль-Байт', 'История ислама'] }, { 'title': 'Фатима аз-Захра: Аудио лекции', 'slogan': 'Образец для верующих женщин в подкастах', - 'description': 'Жизнь, добродетели и положение Фатимы аз-Захры, любимой дочери Пророка Мухаммада. Ее роль как матери Имамов в аудио материалах.' + 'description': 'Жизнь, добродетели и положение Фатимы аз-Захры, любимой дочери Пророка Мухаммада. Ее роль как матери Имамов в аудио материалах.', + 'categories': ['Имамы Ахль аль-Байт', 'Нравственность и этика'] }, { 'title': 'Имам Махди: Аудио о ожидании', 'slogan': 'Подкасты о обещанном спасителе', - 'description': 'Понимание концепции Имама Махди, последнего Имама, который установит справедливость на земле. Признаки его появления в аудио лекциях.' + 'description': 'Понимание концепции Имама Махди, последнего Имама, который установит справедливость на земле. Признаки его появления в аудио лекциях.', + 'categories': ['Имамы Ахль аль-Байт', 'Духовное развитие'] }, { 'title': 'Чудеса пророков: Аудио рассказы', 'slogan': 'Божественные знамения в подкастах', - 'description': 'Исследование чудес, дарованных пророкам Аллахом через аудио. От посоха Мусы до раскола луны Пророком Мухаммадом.' + 'description': 'Исследование чудес, дарованных пророкам Аллахом через аудио. От посоха Мусы до раскола луны Пророком Мухаммадом.', + 'categories': ['Пророки и посланники', 'Коранические истории'] }, { 'title': 'Нравственность Ахль аль-Байт: Аудио', 'slogan': 'Духовное совершенствование через подкасты', - 'description': 'Практические учения Пророка и Имамов о нравственности, этике и духовном росте. Применение исламских принципов в повседневной жизни через аудио.' + 'description': 'Практические учения Пророка и Имамов о нравственности, этике и духовном росте. Применение исламских принципов в повседневной жизни через аудио.', + 'categories': ['Имамы Ахль аль-Байт', 'Нравственность и этика', 'Духовное развитие'] }, { 'title': 'Имам Риза: Аудио наследие', 'slogan': 'Восьмой Имам в аудио лекциях', - 'description': 'Жизнь, дискуссии и мученичество Имама Ризы, восьмого Имама. Его диалоги с учеными различных религий и его роль в распространении знаний.' + 'description': 'Жизнь, дискуссии и мученичество Имама Ризы, восьмого Имама. Его диалоги с учеными различных религий и его роль в распространении знаний.', + 'categories': ['Имамы Ахль аль-Байт', 'Исламская философия', 'История ислама'] } ] @@ -106,6 +117,13 @@ class Command(BaseCommand): status=True ) + # Add categories to playlist + category_titles = playlist_data.get('categories', []) + if category_titles: + categories = PodcastCategory.objects.filter(title__in=category_titles) + playlist.categories.set(categories) + self.stdout.write(f' Added {categories.count()} categories') + self.stdout.write(self.style.SUCCESS(f'✓ Created playlist: {playlist.title}')) # Add all podcasts to this playlist diff --git a/apps/video/management/commands/create_video_categories.py b/apps/video/management/commands/create_video_categories.py new file mode 100644 index 0000000..b0c8061 --- /dev/null +++ b/apps/video/management/commands/create_video_categories.py @@ -0,0 +1,88 @@ +from django.core.management.base import BaseCommand +from django.db import transaction +from apps.video.models import VideoCategory + + +class Command(BaseCommand): + help = 'Create video categories in Russian language' + + # Russian video categories + CATEGORIES_DATA = [ + { + 'title': 'Пророки и посланники', + 'order': 10 + }, + { + 'title': 'Имамы Ахль аль-Байт', + 'order': 20 + }, + { + 'title': 'Коранические истории', + 'order': 30 + }, + { + 'title': 'Исламская философия', + 'order': 40 + }, + { + 'title': 'Нравственность и этика', + 'order': 50 + }, + { + 'title': 'История ислама', + 'order': 60 + }, + { + 'title': 'Кербела и Ашура', + 'order': 70 + }, + { + 'title': 'Духовное развитие', + 'order': 80 + } + ] + + def add_arguments(self, parser): + parser.add_argument( + '--clean', + action='store_true', + help='Delete existing categories before creating new ones' + ) + + def handle(self, *args, **options): + clean = options.get('clean', False) + + if clean: + deleted_count = VideoCategory.objects.count() + VideoCategory.objects.all().delete() + self.stdout.write(self.style.WARNING(f'Deleted {deleted_count} existing categories')) + + try: + with transaction.atomic(): + created_categories = [] + + for category_data in self.CATEGORIES_DATA: + # Check if category already exists + title = category_data['title'] + category, created = VideoCategory.objects.get_or_create( + title=title, + defaults={ + 'order': category_data['order'], + 'status': True + } + ) + + if created: + self.stdout.write(self.style.SUCCESS(f'✓ Created category: {category.title}')) + created_categories.append(category) + else: + self.stdout.write(self.style.WARNING(f'⚠ Category already exists: {category.title}')) + + if created_categories: + self.stdout.write(self.style.SUCCESS(f'\n✓ Successfully created {len(created_categories)} categories!')) + else: + self.stdout.write(self.style.WARNING('\nNo new categories created (all already exist)')) + + except Exception as e: + self.stdout.write(self.style.ERROR(f'\n✗ Error during creation: {str(e)}')) + raise diff --git a/apps/video/management/commands/create_video_playlists.py b/apps/video/management/commands/create_video_playlists.py index 6b23b70..eaa04a4 100644 --- a/apps/video/management/commands/create_video_playlists.py +++ b/apps/video/management/commands/create_video_playlists.py @@ -1,63 +1,74 @@ import random from django.core.management.base import BaseCommand from django.db import transaction -from apps.video.models import Video, VideoPlaylist, PlaylistItem +from apps.video.models import Video, VideoPlaylist, PlaylistItem, VideoCategory class Command(BaseCommand): help = 'Create 10 video playlists in Russian language about prophets and imams, and add all videos to each playlist' # Russian playlist data about prophets and imams + # Each playlist has associated category titles PLAYLISTS_DATA = [ { 'title': 'Жизнь Пророка Мухаммада (да благословит его Аллах)', 'slogan': 'Изучение жизни последнего пророка', - 'description': 'Полная коллекция лекций о жизни, учениях и наследии Пророка Мухаммада (мир ему и благословение Аллаха). Узнайте о его миссии, характере и влиянии на человечество.' + 'description': 'Полная коллекция лекций о жизни, учениях и наследии Пророка Мухаммада (мир ему и благословение Аллаха). Узнайте о его миссии, характере и влиянии на человечество.', + 'categories': ['Пророки и посланники', 'История ислама'] }, { 'title': 'Истории пророков в Коране', 'slogan': 'Коранические повествования о посланниках Аллаха', - 'description': 'Глубокое изучение историй пророков, упомянутых в Священном Коране. От Адама до Мухаммада (мир им всем), узнайте об их испытаниях, учениях и вере.' + 'description': 'Глубокое изучение историй пророков, упомянутых в Священном Коране. От Адама до Мухаммада (мир им всем), узнайте об их испытаниях, учениях и вере.', + 'categories': ['Пророки и посланники', 'Коранические истории'] }, { 'title': 'Имам Али: Врата знаний', 'slogan': 'Мудрость и наследие первого Имама', - 'description': 'Исследование жизни, учений и мудрости Имама Али ибн Аби Талиба, двоюродного брата и зятя Пророка Мухаммада. Его речи, письма и руководство.' + 'description': 'Исследование жизни, учений и мудрости Имама Али ибн Аби Талиба, двоюродного брата и зятя Пророка Мухаммада. Его речи, письма и руководство.', + 'categories': ['Имамы Ахль аль-Байт', 'Исламская философия'] }, { 'title': 'Имам Хусейн и трагедия Кербелы', 'slogan': 'Жертва ради истины и справедливости', - 'description': 'Полное понимание событий Ашуры и мученичества Имама Хусейна. Узнайте о его стойкости против угнетения и его вечном послании человечеству.' + 'description': 'Полное понимание событий Ашуры и мученичества Имама Хусейна. Узнайте о его стойкости против угнетения и его вечном послании человечеству.', + 'categories': ['Имамы Ахль аль-Байт', 'Кербела и Ашура', 'История ислама'] }, { 'title': 'Двенадцать Имамов Ахль аль-Байт', 'slogan': 'Светильники руководства', - 'description': 'Всестороннее изучение жизни и учений двенадцати непогрешимых Имамов из рода Пророка. Их роль в сохранении истинного ислама.' + 'description': 'Всестороннее изучение жизни и учений двенадцати непогрешимых Имамов из рода Пророка. Их роль в сохранении истинного ислама.', + 'categories': ['Имамы Ахль аль-Байт', 'История ислама'] }, { 'title': 'Фатима аз-Захра: Дочь Пророка', 'slogan': 'Образец для верующих женщин', - 'description': 'Жизнь, добродетели и положение Фатимы аз-Захры, любимой дочери Пророка Мухаммада. Ее роль как матери Имамов и ее духовное величие.' + 'description': 'Жизнь, добродетели и положение Фатимы аз-Захры, любимой дочери Пророка Мухаммада. Ее роль как матери Имамов и ее духовное величие.', + 'categories': ['Имамы Ахль аль-Байт', 'Нравственность и этика'] }, { 'title': 'Имам Махди: Обещанный спаситель', 'slogan': 'Ожидание и подготовка к появлению', - 'description': 'Понимание концепции Имама Махди, последнего Имама, который установит справедливость на земле. Признаки его появления и наша роль в ожидании.' + 'description': 'Понимание концепции Имама Махди, последнего Имама, который установит справедливость на земле. Признаки его появления и наша роль в ожидании.', + 'categories': ['Имамы Ахль аль-Байт', 'Духовное развитие'] }, { 'title': 'Пророки и их чудеса', 'slogan': 'Божественные знамения и доказательства', - 'description': 'Исследование чудес, дарованных пророкам Аллахом. От посоха Мусы до раскола луны Пророком Мухаммадом, узнайте о знамениях Всевышнего.' + 'description': 'Исследование чудес, дарованных пророкам Аллахом. От посоха Мусы до раскола луны Пророком Мухаммадом, узнайте о знамениях Всевышнего.', + 'categories': ['Пророки и посланники', 'Коранические истории'] }, { 'title': 'Учения Ахль аль-Байт о нравственности', 'slogan': 'Духовное совершенствование через Ислам', - 'description': 'Практические учения Пророка и Имамов о нравственности, этике и духовном росте. Применение исламских принципов в повседневной жизни.' + 'description': 'Практические учения Пророка и Имамов о нравственности, этике и духовном росте. Применение исламских принципов в повседневной жизни.', + 'categories': ['Имамы Ахль аль-Байт', 'Нравственность и этика', 'Духовное развитие'] }, { 'title': 'Имам Риза и его наследие', 'slogan': 'Восьмой Имам и его вклад', - 'description': 'Жизнь, дискуссии и мученичество Имама Ризы, восьмого Имама. Его диалоги с учеными различных религий и его роль в распространении знаний.' + 'description': 'Жизнь, дискуссии и мученичество Имама Ризы, восьмого Имама. Его диалоги с учеными различных религий и его роль в распространении знаний.', + 'categories': ['Имамы Ахль аль-Байт', 'Исламская философия', 'История ислама'] } ] @@ -106,6 +117,13 @@ class Command(BaseCommand): status=True ) + # Add categories to playlist + category_titles = playlist_data.get('categories', []) + if category_titles: + categories = VideoCategory.objects.filter(title__in=category_titles) + playlist.categories.set(categories) + self.stdout.write(f' Added {categories.count()} categories') + self.stdout.write(self.style.SUCCESS(f'✓ Created playlist: {playlist.title}')) # Add all videos to this playlist with random priority