From 551697c79894b9f2e0288a563caa6a6d04a762ec Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Sat, 24 Oct 2026 11:37:42 +0330 Subject: [PATCH] feat(hadis): add multilingual seed command for transmitter reliabilities and author rutbas --- .../commands/seed_reliabilities_and_rutbas.py | 556 ++++++++++++++++++ 1 file changed, 556 insertions(+) create mode 100644 apps/hadis/management/commands/seed_reliabilities_and_rutbas.py diff --git a/apps/hadis/management/commands/seed_reliabilities_and_rutbas.py b/apps/hadis/management/commands/seed_reliabilities_and_rutbas.py new file mode 100644 index 0000000..914974e --- /dev/null +++ b/apps/hadis/management/commands/seed_reliabilities_and_rutbas.py @@ -0,0 +1,556 @@ +# backend/apps/hadis/management/commands/seed_reliabilities_and_rutbas.py + +import os +import sys +import django +from django.core.management.base import BaseCommand +from django.db import transaction + +# Setup django if executed directly +if __name__ == "__main__": + sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../.."))) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base") + django.setup() + +from apps.hadis.models import TransmitterReliability, BookAuthorRutba + + +# ============================================================================== +# CANONICAL TRANSMITTER RELIABILITIES (وضعیت راویان) +# ============================================================================== + +RELIABILITY_DEFINITIONS = [ + { + "key": "very_reliable", + "match_slugs": ["very-reliable", "супернадежный"], + "default_slug": "very-reliable", + "color": "green", + "title": [ + {"language_code": "ar", "title": "ثقة ثقة (ثبت)", "text": "ثقة ثقة (ثبت)"}, + {"language_code": "ru", "title": "Очень надежный (Суперисточник)", "text": "Очень надежный (Суперисточник)"}, + {"language_code": "en", "title": "Very Reliable (Highest Trust)", "text": "Very Reliable (Highest Trust)"}, + {"language_code": "fa", "title": "بسیار قابل اعتماد (ثقه ثقه)", "text": "بسیار قابل اعتماد (ثقه ثقه)"}, + ], + "description": [ + { + "language_code": "ar", + "title": "راوٍ في أعلى درجات التوثيق والعدالة والضبط", + "text": "راوٍ في أعلى درجات التوثيق والعدالة والضبط، متقن لحفظه وروايته، تُقبل رواياته وتعتبر من أصح الأسانيد وتُقدم عند التعارض.", + }, + { + "language_code": "ru", + "title": "Передатчик наивысшей степени надежности и точности", + "text": "Передатчик наивысшей степени надежности, точности и справедливости. Его предания считаются достоверными и служат веским доводом в шариатских вопросах.", + }, + { + "language_code": "en", + "title": "A narrator of the highest degree of trustworthiness", + "text": "A narrator of the highest degree of trustworthiness, precision, and moral integrity. His narrations are considered authentic and serve as core foundational proof.", + }, + ], + }, + { + "key": "reliable", + "match_slugs": ["reliable", "надежный"], + "default_slug": "reliable", + "color": "blue", + "title": [ + {"language_code": "ar", "title": "ثقة", "text": "ثقة"}, + {"language_code": "ru", "title": "Надежный (Сика)", "text": "Надежный (Сика)"}, + {"language_code": "en", "title": "Reliable (Thiqah)", "text": "Reliable (Thiqah)"}, + {"language_code": "fa", "title": "قابل اعتماد (ثقه)", "text": "قابل اعتماد (ثقه)"}, + ], + "description": [ + { + "language_code": "ar", + "title": "راوٍ عدل ضابط متفق على أمانته", + "text": "راوٍ عدل ضابط متفق على أمانته وصدقه، تقبل أخباره ويُحتج بحديثه في الأحکام الشرعية والأصول.", + }, + { + "language_code": "ru", + "title": "Достоверный и добросовестный передатчик", + "text": "Достоверный, справедливый и добросовестный передатчик с проверенной точностью передачи. Его хадисы принимаются как авторитетный довод.", + }, + { + "language_code": "en", + "title": "A trustworthy and upright narrator", + "text": "A trustworthy and upright narrator whose accuracy is established. His narrations are accepted and cited as authoritative proof.", + }, + ], + }, + { + "key": "acceptable", + "match_slugs": ["acceptable", "правдивый"], + "default_slug": "acceptable", + "color": "yellow", + "title": [ + {"language_code": "ar", "title": "صدوق (حسن الحديث)", "text": "صدوق (حسن الحديث)"}, + {"language_code": "ru", "title": "Приемлемый (Правдивый / Садук)", "text": "Приемлемый (Правдивый / Садук)"}, + {"language_code": "en", "title": "Acceptable (Truthful / Hasan)", "text": "Acceptable (Truthful / Hasan)"}, + {"language_code": "fa", "title": "قابل قبول (صدوق / حسن)", "text": "قابل قبول (صدوق / حسن)"}, + ], + "description": [ + { + "language_code": "ar", + "title": "راوٍ صادق في نفسه لم يبلغ تمام الضبط", + "text": "راوٍ صادق في نفسه لم يبلغ تمام الضبط، حديثه في مرتبة الحسن ويصلح للاحتجاج به أو المتابعة والاعتبار.", + }, + { + "language_code": "ru", + "title": "Правдивый передатчик с хорошей репутацией", + "text": "Правдивый передатчик, чья точность передачи немного уступает высшей степени. Его хадисы считаются хорошими (хасан) и принимаются во внимание.", + }, + { + "language_code": "en", + "title": "A truthful narrator of good standing", + "text": "A truthful narrator whose precision is moderately lower than the highest standard. His hadiths are considered good (hasan) and accepted.", + }, + ], + }, + { + "key": "weak", + "match_slugs": ["weak", "слабый"], + "default_slug": "weak", + "color": "orange", + "title": [ + {"language_code": "ar", "title": "ضعيف", "text": "ضعيف"}, + {"language_code": "ru", "title": "Слабый (Даиф)", "text": "Слабый (Даиф)"}, + {"language_code": "en", "title": "Weak (Da'if)", "text": "Weak (Da'if)"}, + {"language_code": "fa", "title": "ضعیف", "text": "ضعیف"}, + ], + "description": [ + { + "language_code": "ar", + "title": "راوٍ خف ضبطه أو كثرت أخطاؤه", + "text": "راوٍ خف ضبطه أو كثرت أوهامه وأخطاؤه، فلا يُحتج بما ينفرد به، لكن يُستأنس بحديثه في الشواهد والمتابعات إذا لم يكن شديد الضعف.", + }, + { + "language_code": "ru", + "title": "Передатчик со слабой памятью или частыми ошибками", + "text": "Передатчик со слабой памятью или частыми ошибками; его предания не служат самостоятельным доказательством, но могут учитываться как свидетельство.", + }, + { + "language_code": "en", + "title": "A narrator with memory shortcomings", + "text": "A narrator with shortcomings in memory or precision; his solitary narrations cannot serve as independent proof but may serve as corroboration.", + }, + ], + }, + { + "key": "very_weak", + "match_slugs": ["very-weak", "очень-слабый"], + "default_slug": "very-weak", + "color": "red", + "title": [ + {"language_code": "ar", "title": "متروك (شديد الضعف)", "text": "متروك (شديد الضعف)"}, + {"language_code": "ru", "title": "Очень слабый (Матрук / Неприемлемый)", "text": "Очень слабый (Матрук / Неприемлемый)"}, + {"language_code": "en", "title": "Very Weak (Discarded / Fabricator)", "text": "Very Weak (Discarded / Fabricator)"}, + {"language_code": "fa", "title": "بسیار ضعیف (متروک)", "text": "بسیار ضعیف (متروک)"}, + ], + "description": [ + { + "language_code": "ar", + "title": "راوٍ متروك الحديث ساقط الرواية", + "text": "راوٍ اتُّهم بالكذب أو ظهرت منه الغفلة الفاحشة ورواية المنكرات، متروك الحديث ساقط الرواية لا يُعتد بما يرويه ولا يُعتبر بحديثه.", + }, + { + "language_code": "ru", + "title": "Отвергаемый передатчик", + "text": "Отвергаемый передатчик, уличенный во лжи, крайней халатности или передаче вымышленных сообщений; его предания полностью отвергаются.", + }, + { + "language_code": "en", + "title": "A rejected narrator", + "text": "A rejected narrator suspected of fabrication, gross negligence, or narrating anomalies; his reports are discarded and cannot be used as proof.", + }, + ], + }, + { + "key": "unknown", + "match_slugs": ["unknown"], + "default_slug": "unknown", + "color": "gray", + "title": [ + {"language_code": "ar", "title": "مجهول الحال", "text": "مجهول الحال"}, + {"language_code": "ru", "title": "Неизвестный (Маджхуль)", "text": "Неизвестный (Маджхуль)"}, + {"language_code": "en", "title": "Unknown (Majhul)", "text": "Unknown (Majhul)"}, + {"language_code": "fa", "title": "نامشخص (مجهول)", "text": "نامشخص (مجهول)"}, + ], + "description": [ + { + "language_code": "ar", + "title": "راوٍ لم يُعرف حاله وتوثيقه", + "text": "راوٍ لم يُعرف حاله وتوثيقه عند علماء الرجال، أو لم يروِ عنه إلا راوٍ واحد ولم يوثقه معتبر، يتوقف في حديثه حتى يتبين أمره.", + }, + { + "language_code": "ru", + "title": "Неизвестный передатчик", + "text": "Неизвестный передатчик, сведения о надежности которого отсутствуют в книгах по риджалю; принятие его преданий откладывается до выяснения.", + }, + { + "language_code": "en", + "title": "An obscure undocumented narrator", + "text": "An obscure narrator whose identity or credibility is not documented by biographical scholars; judgment on his narrations is withheld.", + }, + ], + }, + { + "key": "companion", + "match_slugs": ["сподвижник", "companion", "sahabi"], + "default_slug": "companion", + "color": "purple", + "title": [ + {"language_code": "ar", "title": "صحابي", "text": "صحابي"}, + {"language_code": "ru", "title": "Сподвижник (Сахаби)", "text": "Сподвижник (Сахаби)"}, + {"language_code": "en", "title": "Companion (Sahabi)", "text": "Companion (Sahabi)"}, + {"language_code": "fa", "title": "صحابی", "text": "صحابی"}, + ], + "description": [ + { + "language_code": "ar", + "title": "صحابي جليل عاصر النبي (ص) أو المعصوم (ع)", + "text": "صحابي جليل عاصر النبي (ص) أو المعصوم (ع)، وتخضع الرواية المنقولة عنه لدراسة اتصال السند والقرائن التاريخية.", + }, + { + "language_code": "ru", + "title": "Признанный сподвижник", + "text": "Признанный сподвижник, современник Пророка (с) или Непорочного (а); предания от него исследуются на предмет непрерывности иснада.", + }, + { + "language_code": "en", + "title": "A recognized companion", + "text": "A recognized companion who lived during the era of the Prophet (pbuh) or Infallible (as), studied in the context of chain continuity.", + }, + ], + }, +] + + +# ============================================================================== +# CANONICAL BOOK AUTHOR RUTBAS (رتبه‌های نویسندگان / مؤلفین) +# ============================================================================== + +RUTBA_DEFINITIONS = [ + { + "slug": "allamah", + "color": "green", + "title": [ + {"language_code": "ar", "title": "علامة ومحقق كبير", "text": "علامة ومحقق كبير"}, + {"language_code": "ru", "title": "Выдающийся ученый (Аллама)", "text": "Выдающийся ученый (Аллама)"}, + {"language_code": "en", "title": "Grand Scholar / Eminent Authority (Allamah)", "text": "Grand Scholar / Eminent Authority (Allamah)"}, + {"language_code": "fa", "title": "علامه و محقق برجسته", "text": "علامه و محقق برجسته"}, + ], + "description": [ + { + "language_code": "ar", + "title": "عالم جليل ومحدث ثبت من كبار أعلام الفقه والحديث والتفسير", + "text": "عالم جليل ومحدث ثبت من كبار أعلام الفقه والحديث والتفسير، مصنفاته تعتبر مراجع أصلية وأعمدة في المكتبة الإسلامية.", + }, + { + "language_code": "ru", + "title": "Выдающийся авторитетный богослов и исследователь высшего ранга", + "text": "Выдающийся авторитетный богослов и исследователь высшего ранга, чьи труды служат фундаментальными первоисточниками.", + }, + { + "language_code": "en", + "title": "A distinguished scholar of the highest standing", + "text": "A distinguished and authoritative scholar of highest standing in Islamic jurisprudence, hadith and commentary, whose works are foundational references.", + }, + ], + }, + { + "slug": "reliable-author", + "color": "blue", + "title": [ + {"language_code": "ar", "title": "مؤلف ثقة معتمد", "text": "مؤلف ثقة معتمد"}, + {"language_code": "ru", "title": "Надежный признанный автор (Сика)", "text": "Надежный признанный автор (Сика)"}, + {"language_code": "en", "title": "Reliable & Authoritative Author", "text": "Reliable & Authoritative Author"}, + {"language_code": "fa", "title": "نویسنده معتمد و ثقه", "text": "نویسنده معتمد و ثقه"}, + ], + "description": [ + { + "language_code": "ar", + "title": "مؤلف متقن وأمين في نقله وتصنيفه", + "text": "مؤلف متقن وأمين في نقله وتصنيفه، حظيت كتبه بالقبول والاعتماد لدى أهل التحقيق ويُعتمد على ما دونه في مصنفاته.", + }, + { + "language_code": "ru", + "title": "Добросовестный и точный в цитировании автор", + "text": "Добросовестный и точный в цитировании автор, чьи книги получили широкое признание и считаются авторитетными среди ученых.", + }, + { + "language_code": "en", + "title": "A trustworthy author of scientific integrity", + "text": "A trustworthy, precise author known for scientific integrity, widely accepted and relied upon by classical and modern researchers.", + }, + ], + }, + { + "slug": "acceptable-author", + "color": "yellow", + "title": [ + {"language_code": "ar", "title": "مؤلف صدوق (حسن النقل)", "text": "مؤلف صدوق (حسن النقل)"}, + {"language_code": "ru", "title": "Правдивый автор (Садук / Приемлемый)", "text": "Правдивый автор (Садук / Приемлемый)"}, + {"language_code": "en", "title": "Truthful / Acceptable Author", "text": "Truthful / Acceptable Author"}, + {"language_code": "fa", "title": "نویسنده صدوق و مورد قبول", "text": "نویسنده صدوق و مورد قبول"}, + ], + "description": [ + { + "language_code": "ar", + "title": "مؤلف صادق وأمين في نقله وأخباره", + "text": "مؤلف صادق وأمين في نقله وأخباره، كُتبه نافعة وتُستفاد في الشواهد والفوائد العلمية.", + }, + { + "language_code": "ru", + "title": "Правдивый автор с хорошей репутацией", + "text": "Правдивый и искренний автор, чьи труды полезны и служат ценным дополнительным источником в научных исследованиях.", + }, + { + "language_code": "en", + "title": "A truthful author of good repute", + "text": "A truthful author of good repute whose writings are valuable, providing useful context and supporting historical evidence.", + }, + ], + }, + { + "slug": "historian", + "color": "purple", + "title": [ + {"language_code": "ar", "title": "مؤرخ وأخباري", "text": "مؤرخ وأخباري"}, + {"language_code": "ru", "title": "Историк и летописец (Ахбари)", "text": "Историк и летописец (Ахбари)"}, + {"language_code": "en", "title": "Historian & Chronicler", "text": "Historian & Chronicler"}, + {"language_code": "fa", "title": "مورخ و اخباری", "text": "مورخ و اخباری"}, + ], + "description": [ + { + "language_code": "ar", + "title": "مؤلف متخصص في تدوين الأخبار والوقائع التاريخية", + "text": "مؤلف متخصص في تدوين الأخبار والوقائع التاريخية والسير والتراجم، تُعتمد كتبه في معرفة الأحداث والتواريخ مع التحقيق والنقد.", + }, + { + "language_code": "ru", + "title": "Ученый-историк и хроникер", + "text": "Ученый, специализирующийся на летописях, исторических хрониках и биографиях; его труды ценны для понимания исторического контекста.", + }, + { + "language_code": "en", + "title": "A scholar specialized in historical chronicles", + "text": "A scholar specialized in compiling historical chronicles, biographies, and events, essential for historical documentation.", + }, + ], + }, + { + "slug": "linguist", + "color": "orange", + "title": [ + {"language_code": "ar", "title": "أديب ولغوي", "text": "أديب ولغوي"}, + {"language_code": "ru", "title": "Филолог и литератор (Адиб)", "text": "Филолог и литератор (Адиб)"}, + {"language_code": "en", "title": "Philologist & Linguist", "text": "Philologist & Linguist"}, + {"language_code": "fa", "title": "ادیب و لغت‌شناس", "text": "ادیب و لغت‌شناس"}, + ], + "description": [ + { + "language_code": "ar", + "title": "متخصص في علوم اللغة العربية والمعاجم والشعر", + "text": "متخصص في علوم اللغة العربية والمعاجم والشعر وغريب الألفاظ، مؤلفاته مرجعية في تحقيق المعاني والدلالات اللغوية.", + }, + { + "language_code": "ru", + "title": "Специалист по арабскому языку и филологии", + "text": "Специалист по арабскому языку, литературе, грамматике и лексикографии; его работы служат стандартом языкового анализа.", + }, + { + "language_code": "en", + "title": "A specialist in Arabic linguistics and philology", + "text": "Specialized in Arabic language, lexicography, poetry, and grammar, whose books are references for linguistic and semantic analysis.", + }, + ], + }, + { + "slug": "unreliable-author", + "color": "red", + "title": [ + {"language_code": "ar", "title": "مؤلف ضعيف (غير معتمد)", "text": "مؤلف ضعيف (غير معتمد)"}, + {"language_code": "ru", "title": "Ненадежный автор (Даиф)", "text": "Ненадежный автор (Даиф)"}, + {"language_code": "en", "title": "Weak / Unreliable Author", "text": "Weak / Unreliable Author"}, + {"language_code": "fa", "title": "نویسنده ضعیف (غیرمعتمد)", "text": "نویسنده ضعیف (غیرمعتمد)"}, + ], + "description": [ + { + "language_code": "ar", + "title": "مؤلف كثرت في مصنفاته الأوهام والنقول الضعيفة", + "text": "مؤلف كثرت في مصنفاته الأوهام والنقول الضعيفة أو غير المحررة، فلا يُعتمد على ما ينفرد بنقله دون شواهد معتبرة.", + }, + { + "language_code": "ru", + "title": "Автор со слабыми и неподтвержденными сведениями", + "text": "Автор, в чьих работах встречается множество неточностей и слабых сообщений; его единоличные утверждения требуют проверки.", + }, + { + "language_code": "en", + "title": "An unverified and inaccurate author", + "text": "An author whose compilations contain significant inaccuracies or unverified reports; single-sourced reports from him are not standalone evidence.", + }, + ], + }, + { + "slug": "unknown-author", + "color": "gray", + "title": [ + {"language_code": "ar", "title": "مؤلف غير مبين الرتبة", "text": "مؤلف غير مبين الرتبة"}, + {"language_code": "ru", "title": "Неопределенный ранг / Неизвестный автор", "text": "Неопределенный ранг / Неизвестный автор"}, + {"language_code": "en", "title": "Unknown / Unclassified Author", "text": "Unknown / Unclassified Author"}, + {"language_code": "fa", "title": "نویسنده نامشخص (غیرمبین)", "text": "نویسنده نامشخص (غیرمبین)"}, + ], + "description": [ + { + "language_code": "ar", + "title": "مؤلف لم تتوفر عنه ترجمة كافية", + "text": "مؤلف لم تتوفر عنه ترجمة كافية في مصادر التراجم لبيان رتبته العلمية ومدى ضبطه وأمانته في النقل بدقة.", + }, + { + "language_code": "ru", + "title": "Автор с недостаточными биографическими данными", + "text": "Автор, о биографии и научной надежности которого сохранилось недостаточно сведений для точной классификации.", + }, + { + "language_code": "en", + "title": "Author with insufficient biographical data", + "text": "An author for whom insufficient biographical information exists in classical sources to determine a precise scholarly rating.", + }, + ], + }, +] + + +def match_definition(record_slug: str): + slug_lower = (record_slug or "").lower() + for definition in RELIABILITY_DEFINITIONS: + for pattern in definition["match_slugs"]: + if pattern in slug_lower: + return definition + return None + + +def match_rutba_definition(record_slug: str): + slug_lower = (record_slug or "").lower() + if any(k in slug_lower for k in ["allamah", "allameh"]): + return RUTBA_DEFINITIONS[0] + if any(k in slug_lower for k in ["reliable", "thiqah", "accepted", "ثقه", "ثقة"]): + return RUTBA_DEFINITIONS[1] + if any(k in slug_lower for k in ["acceptable", "hasan", "حسن"]): + return RUTBA_DEFINITIONS[2] + if any(k in slug_lower for k in ["historian", "tarikh", "تاريخ", "مورخ"]): + return RUTBA_DEFINITIONS[3] + if any(k in slug_lower for k in ["linguist", "lugha", "adab", "لغوي"]): + return RUTBA_DEFINITIONS[4] + if any(k in slug_lower for k in ["unreliable", "daif", "weak", "ضعيف"]): + return RUTBA_DEFINITIONS[5] + if any(k in slug_lower for k in ["unknown", "majhul", "مجهول"]): + return RUTBA_DEFINITIONS[6] + return None + + +class Command(BaseCommand): + help = "Seeds and enriches TransmitterReliability descriptions and BookAuthorRutba ranks with AR, RU, and EN metadata." + + def handle(self, *args, **options): + try: + if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8", errors="replace") + except Exception: + pass + + self.stdout.write(self.style.WARNING("Starting to seed Transmitter Reliabilities and Author Rutbas...")) + + def safe_str(val): + return str(val).encode("ascii", errors="replace").decode("ascii") + + updated_rel_count = 0 + created_rel_count = 0 + + with transaction.atomic(): + # 1. Update existing TransmitterReliability records with full descriptions + existing_reliabilities = list(TransmitterReliability.objects.all()) + handled_keys = set() + + for rel in existing_reliabilities: + def_match = match_definition(rel.slug) + if def_match: + rel.description = def_match["description"] + rel.color = def_match["color"] + + # Merge / supplement titles so AR, RU, EN are guaranteed + title_map = {t.get("language_code"): t for t in (rel.title or []) if isinstance(t, dict)} + for canonical_t in def_match["title"]: + code = canonical_t["language_code"] + if code not in title_map or not title_map[code].get("text"): + title_map[code] = canonical_t + rel.title = list(title_map.values()) + + rel.save() + handled_keys.add(def_match["key"]) + updated_rel_count += 1 + self.stdout.write(f" [+] Updated reliability ID {rel.id} ({safe_str(rel.slug)})") + + # Create any canonical reliabilities that did not exist + for defn in RELIABILITY_DEFINITIONS: + if defn["key"] not in handled_keys: + obj, created = TransmitterReliability.objects.get_or_create( + slug=defn["default_slug"], + defaults={ + "title": defn["title"], + "description": defn["description"], + "color": defn["color"], + }, + ) + if created: + created_rel_count += 1 + self.stdout.write(f" [+] Created canonical reliability: {safe_str(defn['default_slug'])}") + + # 2. Seed and update BookAuthorRutba objects + created_rutba_count = 0 + updated_rutba_count = 0 + handled_rutba_keys = set() + + # First update any existing rutbas + for rutba in BookAuthorRutba.objects.all(): + match = match_rutba_definition(rutba.slug) + if match: + rutba.description = match["description"] + rutba.color = match["color"] + title_map = {t.get("language_code"): t for t in (rutba.title or []) if isinstance(t, dict)} + for canonical_t in match["title"]: + code = canonical_t["language_code"] + if code not in title_map or not title_map[code].get("text"): + title_map[code] = canonical_t + rutba.title = list(title_map.values()) + rutba.save() + handled_rutba_keys.add(match["slug"]) + updated_rutba_count += 1 + self.stdout.write(f" [+] Updated existing author rutba: {safe_str(rutba.slug)}") + + # Create any canonical rutbas that don't exist yet + for defn in RUTBA_DEFINITIONS: + slug = defn["slug"] + existing = BookAuthorRutba.objects.filter(slug=slug).first() + if not existing: + BookAuthorRutba.objects.create( + slug=slug, + title=defn["title"], + description=defn["description"], + color=defn["color"], + ) + created_rutba_count += 1 + self.stdout.write(f" [+] Created canonical author rutba: {safe_str(slug)}") + + self.stdout.write(self.style.SUCCESS( + f"\nDone!" + f"\n Transmitter Reliabilities: {updated_rel_count} updated, {created_rel_count} created." + f"\n Book Author Rutbas: {created_rutba_count} created, {updated_rutba_count} updated." + )) + + +if __name__ == "__main__": + cmd = Command() + cmd.handle()