You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

555 lines
19 KiB

#!/usr/bin/env python3
"""
Script to update all transmitters in the database with 80+ distinct, authentic
narrator names across English (en), Arabic (ar), and Russian (ru).
Strictly conforms to the project's multilingual JSON structure:
[
{"language_code": "en", "text": "..."},
{"language_code": "ar", "text": "..."},
{"language_code": "ru", "text": "..."}
]
and regenerates unique, clean slugs for each transmitter.
"""
import os
import sys
import argparse
from pathlib import Path
# Force UTF-8 encoding for console output on Windows
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8")
if hasattr(sys.stderr, "reconfigure"):
sys.stderr.reconfigure(encoding="utf-8")
BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(BASE_DIR))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.base")
import django
django.setup()
from django.db import transaction
from django.utils.text import slugify
from apps.hadis.models import Transmitters
# 90 Authentic, prominent Hadith narrators and scholars
TRANSMITTER_NAMES = [
{
"en": "Zurarah ibn A'yan",
"ar": "زرارة بن أعين",
"ru": "Зурара ибн Аян",
},
{
"en": "Muhammad ibn Muslim",
"ar": "محمد بن مسلم",
"ru": "Мухаммад ибн Муслим",
},
{
"en": "Abu Basir al-Asadi",
"ar": "أبو بصير الأسدي",
"ru": "Абу Басир аль-Асади",
},
{
"en": "Jamil ibn Darraj",
"ar": "جميل بن دراج",
"ru": "Джамиль ибн Даррадж",
},
{
"en": "Burayd ibn Mu'awiyah al-Ijli",
"ar": "بريد بن معاوية العجلي",
"ru": "Бурайд ибн Муавия аль-Иджли",
},
{
"en": "Al-Fudayl ibn Yasar",
"ar": "الفضيل بن يسار",
"ru": "Аль-Фудайль ибн Йасар",
},
{
"en": "Aban ibn Taghlib",
"ar": "أبان بن تغلب",
"ru": "Абан ибн Таглиб",
},
{
"en": "Hisham ibn al-Hakam",
"ar": "هشام بن الحكم",
"ru": "Хишам ибн аль-Хакам",
},
{
"en": "Hisham ibn Salim al-Jawaliqi",
"ar": "هشام بن سالم الجواليقي",
"ru": "Хишам ибн Салим аль-Джавалики",
},
{
"en": "Yunus ibn Abd al-Rahman",
"ar": "يونس بن عبد الرحمن",
"ru": "Йунус ибн Абд ар-Рахман",
},
{
"en": "Safwan ibn Yahya",
"ar": "صفوان بن يحيى",
"ru": "Сафван ибн Йахья",
},
{
"en": "Muhammad ibn Abi Umayr",
"ar": "محمد بن أبي عمير",
"ru": "Мухаммад ибн Аби Умайр",
},
{
"en": "Ahmad ibn Muhammad ibn Abi Nasr al-Bazanti",
"ar": "أحمد بن محمد بن أبي نصر البزنطي",
"ru": "Ахмад ибн Мухаммад аль-Базанти",
},
{
"en": "Hammad ibn Isa",
"ar": "حماد بن عيسى",
"ru": "Хаммад ибн Иса",
},
{
"en": "Hammad ibn Uthman",
"ar": "حماد بن عثمان",
"ru": "Хаммад ибн Усман",
},
{
"en": "Mu'awiyah ibn Ammar",
"ar": "معاوية بن عمار",
"ru": "Муавия ибн Аммар",
},
{
"en": "Ali ibn Yaqtin",
"ar": "علي بن يقطين",
"ru": "Али ибн Йактин",
},
{
"en": "Zakariya ibn Adam al-Qummi",
"ar": "زكريا بن آدم القمي",
"ru": "Закария ибн Адам аль-Кумми",
},
{
"en": "Al-Fadl ibn Shadhan",
"ar": "الفضل بن شاذان",
"ru": "Аль-Фадль ибн Шазан",
},
{
"en": "Muhammad ibn Ya'qub al-Kulayni",
"ar": "محمد بن يعقوب الكليني",
"ru": "Мухаммад ибн Йакуб аль-Кулайни",
},
{
"en": "Al-Shaykh al-Saduq (Muhammad ibn Ali ibn Babawayh)",
"ar": "الشيخ الصدوق (محمد بن علي بن بابويه)",
"ru": "Аш-Шейх ас-Садук",
},
{
"en": "Al-Shaykh al-Mufid (Muhammad ibn Muhammad al-Nu'man)",
"ar": "الشيخ المفيد (محمد بن محمد النعمان)",
"ru": "Аш-Шейх аль-Муфид",
},
{
"en": "Ali ibn al-Husayn al-Sharif al-Murtada",
"ar": "الشريف المرتضى (علي بن الحسين)",
"ru": "Аш-Шариф аль-Муртада",
},
{
"en": "Al-Shaykh al-Tusi (Muhammad ibn al-Hasan)",
"ar": "الشيخ الطوسي (محمد بن الحسن)",
"ru": "Аш-Шейх ат-Туси",
},
{
"en": "Al-Allamah al-Hilli (Al-Hasan ibn Yusuf)",
"ar": "العلامة الحلي (الحسن بن يوسف)",
"ru": "Аль-Аллама аль-Хилли",
},
{
"en": "Al-Muhaqqiq al-Hilli (Ja'far ibn al-Hasan)",
"ar": "المحقق الحلي (جعفر بن الحسن)",
"ru": "Аль-Мухаккик аль-Хилли",
},
{
"en": "Al-Shahid al-Awwal (Muhammad ibn Makki)",
"ar": "الشهيد الأول (محمد بن مكي)",
"ru": "Аш-Шахид аль-Авваль",
},
{
"en": "Al-Shahid al-Thani (Zayn al-Din al-Jubba'i)",
"ar": "الشهيد الثاني (زين الدين الجبعي)",
"ru": "Аш-Шахид ас-Сани",
},
{
"en": "Muhammad Baqir al-Majlisi",
"ar": "محمد باقر المجلسي",
"ru": "Мухаммад Бакир аль-Маджлиси",
},
{
"en": "Al-Hurr al-Amili (Muhammad ibn al-Hasan)",
"ar": "الحر العاملي (محمد بن الحسن)",
"ru": "Аль-Хурр аль-Амили",
},
{
"en": "Abu al-Qasim al-Khu'i",
"ar": "أبو القاسم الخوئي",
"ru": "Абу аль-Касим аль-Хои",
},
{
"en": "Salman al-Farsi",
"ar": "سلمان الفارسي",
"ru": "Салман аль-Фарси",
},
{
"en": "Abu Dharr al-Ghifari",
"ar": "أبو ذر الغفاري",
"ru": "Абу Зарр аль-Гифари",
},
{
"en": "Al-Miqdad ibn al-Aswad",
"ar": "المقداد بن الأسود",
"ru": "Аль-Микдад ибн аль-Асвад",
},
{
"en": "Ammar ibn Yasir",
"ar": "عمار بن ياسر",
"ru": "Аммар ибн Йасир",
},
{
"en": "Jabir ibn Abd Allah al-Ansari",
"ar": "جابر بن عبد الله الأنصاري",
"ru": "Джабир ибн Абдуллах аль-Ансари",
},
{
"en": "Hudhayfah ibn al-Yaman",
"ar": "حذيفة بن اليمان",
"ru": "Хузайфа ибн аль-Йаман",
},
{
"en": "Malik al-Ashtar al-Nakha'i",
"ar": "مالك الأشتر النخعي",
"ru": "Малик аль-Аштар",
},
{
"en": "Kumayl ibn Ziyad al-Nakha'i",
"ar": "كميل بن زياد النخعي",
"ru": "Кумайль ибн Зийад",
},
{
"en": "Maytham al-Tammar",
"ar": "ميثم التمار",
"ru": "Майсам ат-Таммар",
},
{
"en": "Sa'id ibn Jubayr",
"ar": "سعيد بن جبير",
"ru": "Саид ибн Джубайр",
},
{
"en": "Tawus ibn Kaysan",
"ar": "طاووس بن كيسان",
"ru": "Тавус ибн Кайсан",
},
{
"en": "Sulaym ibn Qays al-Hilali",
"ar": "سليم بن قيس الهلالي",
"ru": "Сулейм ибн Кайс аль-Хилали",
},
{
"en": "Al-Asbagh ibn Nubatah",
"ar": "الأصبغ بن نباتة",
"ru": "Аль-Асбаг ибн Нубата",
},
{
"en": "Jabir ibn Yazid al-Ju'fi",
"ar": "جابر بن يزيد الجعفي",
"ru": "Джабир ибн Йазид аль-Джуфи",
},
{
"en": "Abu Hamzah al-Thumali (Thabit ibn Dinar)",
"ar": "أبو حمزة الثمالي (ثابت بن دينار)",
"ru": "Абу Хамза ас-Сумали",
},
{
"en": "Zayd ibn Ali ibn al-Husayn",
"ar": "زيد بن علي بن الحسين",
"ru": "Зайд ибн Али",
},
{
"en": "Dawud ibn Sarhan",
"ar": "داود بن سرحان",
"ru": "Давуд ибн Сархан",
},
{
"en": "Abd Allah ibn Sinan",
"ar": "عبد الله بن سنان",
"ru": "Абдуллах ибн Синан",
},
{
"en": "Abd Allah ibn Bukayr",
"ar": "عبد الله بن بكير",
"ru": "Абдуллах ибн Букайр",
},
{
"en": "Abd Allah ibn Mughirah",
"ar": "عبد الله بن المغيرة",
"ru": "Абдуллах ибн аль-Мугира",
},
{
"en": "Al-Husayn ibn Sa'id al-Ahwazi",
"ar": "الحسين بن سعيد الأهوازي",
"ru": "Аль-Хусейн ибн Саид аль-Ахвази",
},
{
"en": "Ali ibn Mahziyar al-Ahwazi",
"ar": "علي بن مهزيار الأهوازي",
"ru": "Али ибн Махзийар аль-Ахвази",
},
{
"en": "Ibrahim ibn Hashim al-Qummi",
"ar": "إبراهيم بن هاشم القمي",
"ru": "Ибрахим ибн Хашим аль-Кумми",
},
{
"en": "Ali ibn Ibrahim al-Qummi",
"ar": "علي بن إبراهيم القمي",
"ru": "Али ибн Ибрахим аль-Кумми",
},
{
"en": "Sa'd ibn Abd Allah al-Ash'ari",
"ar": "سعد بن عبد الله الأشعري",
"ru": "Саад ибн Абдуллах аль-Ашари",
},
{
"en": "Al-Hasan ibn Mahbub al-Sarrad",
"ar": "الحسن بن محبوب السراد",
"ru": "Аль-Хасан ибн Махбуб",
},
{
"en": "Al-Hasan ibn Ali ibn Faddal",
"ar": "الحسن بن علي بن فضال",
"ru": "Аль-Хасан ибн Али ибн Фаддаль",
},
{
"en": "Ali ibn al-Hasan ibn Faddal",
"ar": "علي بن الحسن بن فضال",
"ru": "Али ибн аль-Хасан ибн Фаддаль",
},
{
"en": "Muhammad ibn Ahmad ibn Yahya al-Ash'ari",
"ar": "محمد بن أحمد بن يحيى الأشعري",
"ru": "Мухаммад ибн Ахмад ибн Йахья",
},
{
"en": "Ahmad ibn Muhammad ibn Isa al-Ash'ari",
"ar": "أحمد بن محمد بن عيسى الأشعري",
"ru": "Ахмад ибн Мухаммад ибн Иса аль-Ашари",
},
{
"en": "Ahmad ibn Muhammad ibn Khalid al-Barqi",
"ar": "أحمد بن محمد بن خالد البرقي",
"ru": "Ахмад ибн Мухаммад аль-Барки",
},
{
"en": "Muhammad ibn Yahya al-Attar al-Qummi",
"ar": "محمد بن يحيى العطار القمي",
"ru": "Мухаммад ибн Йахья аль-Аттар",
},
{
"en": "Al-Husayn ibn Muhammad al-Ash'ari",
"ar": "الحسين بن محمد الأشعري",
"ru": "Аль-Хусейн ибн Мухаммад аль-Ашари",
},
{
"en": "Ali ibn al-Husayn ibn Babawayh al-Qummi",
"ar": "علي بن الحسين بن بابويه القمي",
"ru": "Али ибн аль-Хусейн ибн Бабавейх",
},
{
"en": "Ja'far ibn Muhammad ibn Qulawayh",
"ar": "جعفر بن محمد بن قولويه",
"ru": "Джафар ибн Мухаммад ибн Кулавейх",
},
{
"en": "Muhammad ibn al-Hasan al-Saffar",
"ar": "محمد بن الحسن الصفار",
"ru": "Мухаммад ибн аль-Хасан ас-Саффар",
},
{
"en": "Muhammad ibn Umar al-Kashshi",
"ar": "محمد بن عمر الكشي",
"ru": "Мухаммад ибн Умар аль-Кашши",
},
{
"en": "Ahmad ibn Ali al-Najashi",
"ar": "أحمد بن علي النجاشي",
"ru": "Ахмад ибн Али ан-Наджаши",
},
{
"en": "Muhammad ibn Ibrahim al-Nu'mani",
"ar": "محمد بن إبراهيم النعماني",
"ru": "Мухаммад ибн Ибрахим ан-Нумани",
},
{
"en": "Qutb al-Din al-Rawandi",
"ar": "قطب الدين الراوندي",
"ru": "Кутб ад-Дин ар-Раванди",
},
{
"en": "Al-Fadl ibn al-Hasan al-Tabrisi",
"ar": "الفضل بن الحسن الطبرسي",
"ru": "Аль-Фадль ибн аль-Хасан ат-Табарси",
},
{
"en": "Ibn Shahrashub al-Mazandarani",
"ar": "ابن شهرآشوب المازندراني",
"ru": "Ибн Шахрашуб аль-Мазандарани",
},
{
"en": "Ali ibn Musa ibn Tawus",
"ar": "علي بن موسى بن طاووس",
"ru": "Али ибн Муса ибн Тавус",
},
{
"en": "Ahmad ibn Muhammad al-Ardabili",
"ar": "أحمد بن محمد الأردبيلي",
"ru": "Ахмад ибн Мухаммад аль-Ардабили",
},
{
"en": "Al-Muhsin al-Fayd al-Kashani",
"ar": "المحسن الفيض الكاشاني",
"ru": "Аль-Файд аль-Кашани",
},
{
"en": "Yusuf ibn Ahmad al-Bahrani",
"ar": "يوسف بن أحمد البحراني",
"ru": "Йусуф ибн Ахмад аль-Бахрани",
},
{
"en": "Murtada al-Ansari",
"ar": "مرتضى الأنصاري",
"ru": "Муртаза аль-Ансари",
},
{
"en": "Muhammad Hasan al-Shirazi",
"ar": "محمد حسن الشيرازي",
"ru": "Мухаммад Хасан аль-Ширази",
},
{
"en": "Muhsin al-Amin al-Amili",
"ar": "محسن الأمين العاملي",
"ru": "Мухсин аль-Амин аль-Амили",
},
{
"en": "Abd al-Husayn Sharaf al-Din al-Musawi",
"ar": "عبد الحسين شرف الدين الموسوي",
"ru": "Абд аль-Хусейн Шараф ад-Дин",
},
{
"en": "Muhammad Baqir al-Sadr",
"ar": "محمد باقر الصدر",
"ru": "Мухаммад Бакир ас-Садр",
},
{
"en": "Muhammad Husayn al-Tabataba'i",
"ar": "محمد حسين الطباطبائي",
"ru": "Мухаммад Хусейн ат-Табатабаи",
},
{
"en": "Al-Hasan ibn Zayn al-Din (Sahib al-Ma'alim)",
"ar": "الحسن بن زين الدين (صاحب المعالم)",
"ru": "Аль-Хасан ибн Зайн ад-Дин",
},
{
"en": "Muhammad Baqir al-Sabzawari",
"ar": "محمد باقر السبزواري",
"ru": "Мухаммад Бакир ас-Сабзавари",
},
{
"en": "Al-Sharif al-Radi (Muhammad ibn al-Husayn)",
"ar": "الشريف الرضي (محمد بن الحسين)",
"ru": "Аш-Шариф ар-Ради",
},
{
"en": "Ibn Abi Aqil al-Umani",
"ar": "ابن أبي عقيل العماني",
"ru": "Ибн Аби Акиль аль-Умани",
},
{
"en": "Ibn al-Junayd al-Iskafi",
"ar": "ابن الجنيد الإسكافي",
"ru": "Ибн аль-Джунайд аль-Искафи",
},
{
"en": "Al-Qadi Ibn al-Barraj",
"ar": "القاضي ابن البراج",
"ru": "Аль-Кади ибн аль-Баррадж",
},
{
"en": "Sallar ibn Abd al-Aziz al-Daylami",
"ar": "سلار بن عبد العزيز الديلمي",
"ru": "Саллар ибн Абд аль-Азиз",
},
]
def update_transmitters(dry_run: bool = False):
transmitters = list(Transmitters.objects.all().order_by("id"))
total_count = len(transmitters)
print(f"Found {total_count} transmitters in database.")
print(f"Loaded {len(TRANSMITTER_NAMES)} curated narrator names.")
if total_count > len(TRANSMITTER_NAMES):
print(f"Warning: Database has {total_count} transmitters, but we have {len(TRANSMITTER_NAMES)} names.")
updated = 0
with transaction.atomic():
for idx, transmitter in enumerate(transmitters):
name_data = TRANSMITTER_NAMES[idx % len(TRANSMITTER_NAMES)]
en_name = name_data["en"]
ar_name = name_data["ar"]
ru_name = name_data["ru"]
# Format strictly adheres to the multilingual JSON schema:
# [{"language_code": "...", "text": "..."}]
new_full_name = [
{"language_code": "en", "text": en_name},
{"language_code": "ar", "text": ar_name},
{"language_code": "ru", "text": ru_name},
]
transmitter.full_name = new_full_name
# Generating a clean, unique slug from the English name
base_slug = slugify(en_name, allow_unicode=True) or f"transmitter-{transmitter.id}"
# Check for conflict excluding current transmitter
candidate_slug = base_slug[:240]
counter = 1
while Transmitters.objects.filter(slug=candidate_slug).exclude(pk=transmitter.pk).exists():
candidate_slug = f"{base_slug[:230]}-{counter}"
counter += 1
transmitter.slug = candidate_slug
if dry_run:
print(f"[DRY RUN] ID {transmitter.id}: {en_name} | {ar_name} | {ru_name} -> slug: {candidate_slug}")
else:
transmitter.save()
print(f"[UPDATED] ID {transmitter.id}: {en_name} | {ar_name} | {ru_name} -> slug: {transmitter.slug}")
updated += 1
if dry_run:
print(f"\n[DRY RUN COMPLETE] {updated} transmitters would be updated. No changes were committed.")
transaction.set_rollback(True)
else:
print(f"\n[SUCCESS] Successfully updated {updated} transmitters with unique multilingual names and slugs.")
def main():
parser = argparse.ArgumentParser(description="Update transmitters with unique multilingual names.")
parser.add_argument("--dry-run", action="store_true", help="Simulate updates without committing to database.")
args = parser.parse_args()
update_transmitters(dry_run=args.dry_run)
if __name__ == "__main__":
main()