From b9a3726de24dd545766555a8cbacf77669d7f69e Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Sat, 24 Jan 2026 11:27:49 +0330 Subject: [PATCH] Add management command to seed multilingual opinion data - Introduced a new management command to seed OpinionStatus, TransmitterOpinion, and TransmitterOriginalText with multilingual data. - Implemented logic to create opinion statuses with corresponding colors and titles in English, Farsi, and Russian. - Added functionality to generate random opinions and original texts for transmitters, ensuring unique titles for each transmitter. - Enhanced data handling for better integration with existing models and improved seeding process. --- .../commands/seed_opinion_originaltexts.py | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 apps/hadis/management/commands/seed_opinion_originaltexts.py diff --git a/apps/hadis/management/commands/seed_opinion_originaltexts.py b/apps/hadis/management/commands/seed_opinion_originaltexts.py new file mode 100644 index 0000000..1545dc2 --- /dev/null +++ b/apps/hadis/management/commands/seed_opinion_originaltexts.py @@ -0,0 +1,197 @@ +import random +from django.core.management.base import BaseCommand +from django.db import transaction +# REPLACE 'apps.hadis.models' with your actual app path +from apps.hadis.models import ( + Transmitters, + OpinionStatus, + TransmitterOpinion, + TransmitterOriginalText +) + +class Command(BaseCommand): + help = 'Seeds OpinionStatus, TransmitterOpinion, and TransmitterOriginalText with multilingual data' + + def create_json(self, en, fa, ru): + """Helper to create the standard JSON structure""" + return [ + {"text": en, "language_code": "en"}, + {"text": fa, "language_code": "fa"}, + {"text": ru, "language_code": "ru"} + ] + + def handle(self, *args, **options): + self.stdout.write("Starting generation of Transmitter details...") + + # ========================================== + # 1. SEED OPINION STATUSES (7 Colors) + # ========================================== + self.stdout.write("Seeding Opinion Statuses...") + + # Mapping colors to Rijal Terminology + status_data = [ + { + "color": OpinionStatus.ColorChoices.GREEN, + "en": "Thiqah (Trustworthy)", "fa": "ثقه (مورد اعتماد)", "ru": "Сика (Достоверный)" + }, + { + "color": OpinionStatus.ColorChoices.BLUE, + "en": "Hasan (Good/Acceptable)", "fa": "حسن (نیکو)", "ru": "Хасан (Хороший)" + }, + { + "color": OpinionStatus.ColorChoices.YELLOW, + "en": "Da'if (Weak)", "fa": "ضعیف", "ru": "Даиф (Слабый)" + }, + { + "color": OpinionStatus.ColorChoices.ORANGE, + "en": "Majhul (Unknown)", "fa": "مجهول (ناشناخته)", "ru": "Маджхуль (Неизвестный)" + }, + { + "color": OpinionStatus.ColorChoices.RED, + "en": "Kadhdhab (Liar/Fabricator)", "fa": "کذاب (دروغگو)", "ru": "Каззаб (Лжец)" + }, + { + "color": OpinionStatus.ColorChoices.PURPLE, + "en": "Mukhtalit (Confused)", "fa": "مختلط (آشفته)", "ru": "Мухталит (Запутанный)" + }, + { + "color": OpinionStatus.ColorChoices.GRAY, + "en": "Matruk (Abandoned)", "fa": "متروک", "ru": "Матрук (Оставленный)" + }, + ] + + created_statuses = [] + + for item in status_data: + # Check if a status with this color already exists to avoid duplication + status, created = OpinionStatus.objects.get_or_create( + color=item["color"], + defaults={ + "title": self.create_json(item["en"], item["fa"], item["ru"]) + } + ) + created_statuses.append(status) + + self.stdout.write(f"Ensured {len(created_statuses)} Opinion Statuses exist.") + + # ========================================== + # DATA POOLS FOR GENERATION + # ========================================== + + scholars_pool = [ + {"en": "Al-Najashi", "fa": "نجاشی", "ru": "Аль-Наджаши"}, + {"en": "Sheikh Al-Tusi", "fa": "شیخ طوسی", "ru": "Шейх ат-Туси"}, + {"en": "Al-Dhahabi", "fa": "ذهبی", "ru": "Аз-Захаби"}, + {"en": "Ibn Hajar", "fa": "ابن حجر", "ru": "Ибн Хаджар"}, + {"en": "Al-Kashi", "fa": "کشی", "ru": "Аль-Кашши"}, + ] + + opinion_texts_pool = [ + { + "en": "He is reliable in narration and clear in method.", + "fa": "او در روایت موثق و در روش واضح است.", + "ru": "Он надежен в передаче и ясен в методе." + }, + { + "en": "There is weakness in his memory regarding dates.", + "fa": "در حافظه او در مورد تاریخ‌ها ضعف وجود دارد.", + "ru": "В его памяти есть слабость касательно дат." + }, + { + "en": "He narrates strange reports (Manakir) from trustworthy people.", + "fa": "او روایات عجیب (مناکیر) را از افراد موثق نقل می‌کند.", + "ru": "Он передает странные сообщения (манакир) от надежных людей." + }, + { + "en": "Highly truthful, but he makes mistakes.", + "fa": "بسیار راستگو است، اما مرتکب اشتباه می‌شود.", + "ru": "Очень правдивый, но совершает ошибки." + }, + { + "en": "His status is unknown to the earlier scholars.", + "fa": "وضعیت او بر علمای متقدم نامعلوم است.", + "ru": "Его статус неизвестен ранним ученым." + } + ] + + original_text_titles = [ + {"en": "Extract from Kitab al-Rijal", "fa": "برگزیده از کتاب الرجال", "ru": "Отрывок из Китаб ар-Риджаль"}, + {"en": "Narration on Jurisprudence", "fa": "روایتی در باب فقه", "ru": "Предание о юриспруденции"}, + {"en": "Commentary on Monotheism", "fa": "شرحی بر توحید", "ru": "Комментарий к Единобожию"}, + {"en": "Biographical Note", "fa": "یادداشت زندگی‌نامه‌ای", "ru": "Биографическая заметка"}, + ] + + original_text_bodies = [ + { + "en": "He narrated: 'Knowledge is the root of all good.'", + "fa": "او روایت کرد: «دانش ریشه تمام خوبی‌هاست.»", + "ru": "Он передал: 'Знание — корень всего блага'." + }, + { + "en": "I heard him say in the gathering of Kufa...", + "fa": "شنیدم که در مجلس کوفه می‌گفت...", + "ru": "Я слышал, как он говорил в собрании Куфы..." + }, + { + "en": "His writing was preserved in the scrolls of his students.", + "fa": "نوشته‌های او در صحیفه‌های شاگردانش محفوظ ماند.", + "ru": "Его писания сохранились в свитках его учеников." + } + ] + + # ========================================== + # 2. SEED TRANSMITTERS + # ========================================== + + transmitters = Transmitters.objects.all() + total_transmitters = transmitters.count() + + if total_transmitters == 0: + self.stdout.write(self.style.WARNING("No transmitters found. Please seed transmitters first.")) + return + + self.stdout.write(f"Processing {total_transmitters} Transmitters...") + + opinions_created = 0 + texts_created = 0 + + for i, transmitter in enumerate(transmitters, 1): + if i % 50 == 0: + self.stdout.write(f"Processing {i}/{total_transmitters}...") + + with transaction.atomic(): + # --- A. Generate 3 Opinions --- + for _ in range(3): + scholar = random.choice(scholars_pool) + op_text = random.choice(opinion_texts_pool) + status = random.choice(created_statuses) + + TransmitterOpinion.objects.create( + transmitter=transmitter, + scholar_name=self.create_json(scholar["en"], scholar["fa"], scholar["ru"]), + opinion_text=self.create_json(op_text["en"], op_text["fa"], op_text["ru"]), + status=status + ) + opinions_created += 1 + + # --- B. Generate 3 Original Texts --- + for k in range(3): + title_base = random.choice(original_text_titles) + body_base = random.choice(original_text_bodies) + + # Make title unique per transmitter to help slug generation + t_en = f"{title_base['en']} - {transmitter.id}-{k}" + t_fa = f"{title_base['fa']} - {transmitter.id}-{k}" + t_ru = f"{title_base['ru']} - {transmitter.id}-{k}" + + TransmitterOriginalText.objects.create( + transmitter=transmitter, + title=self.create_json(t_en, t_fa, t_ru), + text=self.create_json(body_base["en"], body_base["fa"], body_base["ru"]), # Source text + translation=self.create_json(body_base["en"], body_base["fa"], body_base["ru"]), # Translations + ) + texts_created += 1 + + self.stdout.write(self.style.SUCCESS( + f"Done! Created {opinions_created} Opinions and {texts_created} Original Texts." + )) \ No newline at end of file