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.
432 lines
19 KiB
432 lines
19 KiB
"""
|
|
Django management command to seed mock data for hadith collections, references, and corrections.
|
|
Place this file in: yourapp/management/commands/seed_hadis.py
|
|
|
|
Usage: python manage.py seed_hadis
|
|
python manage.py seed_hadis --clear
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from django.core.management.base import BaseCommand
|
|
from django.core.files.base import ContentFile
|
|
from django.utils.text import slugify
|
|
from django.conf import settings
|
|
from apps.hadis.models.hadis import (
|
|
HadisCollection,
|
|
HadisInCollection,
|
|
HadisReference,
|
|
ReferenceImage,
|
|
HadisCorrection,
|
|
Hadis
|
|
)
|
|
from apps.hadis.models.reference import BookReference
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Seed the database with mock hadith collection and reference data'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
'--clear',
|
|
action='store_true',
|
|
help='Clear existing data before seeding',
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
if options['clear']:
|
|
self.stdout.write(self.style.WARNING('Clearing existing hadith data...'))
|
|
ReferenceImage.objects.all().delete()
|
|
HadisCorrection.objects.all().delete()
|
|
HadisReference.objects.all().delete()
|
|
HadisInCollection.objects.all().delete()
|
|
HadisCollection.objects.all().delete()
|
|
self.stdout.write(self.style.SUCCESS('Data cleared successfully!'))
|
|
|
|
# Step 1: Create Hadis Collections
|
|
self.stdout.write(self.style.SUCCESS('\n📚 Creating Hadis Collections...'))
|
|
collections_data = [
|
|
{
|
|
"title": "Purification & Prayer",
|
|
"summary": "Collection of ahadith related to purification (Wudu, Ghusl) and prayer rituals.",
|
|
"status": True,
|
|
"order": 1,
|
|
},
|
|
{
|
|
"title": "Zakat & Charity",
|
|
"summary": "Ahadith discussing the obligation of zakat and charitable giving in Islam.",
|
|
"status": True,
|
|
"order": 2,
|
|
},
|
|
{
|
|
"title": "Fasting & Ramadan",
|
|
"summary": "Collection of authentic ahadith about fasting, its virtues, and Ramadan practices.",
|
|
"status": True,
|
|
"order": 3,
|
|
},
|
|
{
|
|
"title": "Hajj & Umrah",
|
|
"summary": "Ahadith related to the pilgrimage to Mecca and the spiritual practices involved.",
|
|
"status": True,
|
|
"order": 4,
|
|
},
|
|
{
|
|
"title": "Ethics & Morality",
|
|
"summary": "Ahadith emphasizing Islamic ethics, good character, and moral conduct.",
|
|
"status": True,
|
|
"order": 5,
|
|
},
|
|
{
|
|
"title": "Knowledge & Learning",
|
|
"summary": "Collection emphasizing the importance of seeking knowledge in Islam.",
|
|
"status": True,
|
|
"order": 6,
|
|
},
|
|
{
|
|
"title": "Family & Relations",
|
|
"summary": "Ahadith about family relationships, rights of parents, spouses, and children.",
|
|
"status": True,
|
|
"order": 7,
|
|
},
|
|
{
|
|
"title": "Business & Trade",
|
|
"summary": "Ahadith related to ethical business practices and commerce in Islam.",
|
|
"status": True,
|
|
"order": 8,
|
|
},
|
|
]
|
|
|
|
collections = {}
|
|
for collection_data in collections_data:
|
|
collection, created = HadisCollection.objects.get_or_create(
|
|
title=collection_data['title'],
|
|
defaults=collection_data
|
|
)
|
|
collections[collection_data['title']] = collection
|
|
status = '✓ Created' if created else '• Updated'
|
|
self.stdout.write(f"{status}: {collection.title}")
|
|
|
|
# Step 2: Get book references (we'll use all available books)
|
|
self.stdout.write(self.style.SUCCESS('\n📖 Getting Book References...'))
|
|
book_references = BookReference.objects.all()
|
|
if not book_references.exists():
|
|
self.stdout.write(self.style.WARNING('⚠️ No book references found. Run seed_books first!'))
|
|
return
|
|
|
|
book_references_list = list(book_references)
|
|
self.stdout.write(f"✓ Found {len(book_references_list)} book references")
|
|
|
|
# Step 3: Create Hadis References
|
|
self.stdout.write(self.style.SUCCESS('\n🔗 Creating Hadis References...'))
|
|
|
|
hadis_ids = list(range(1800, 1853))
|
|
reference_descriptions = [
|
|
"This hadith is recorded in the collection with full chain of narration.",
|
|
"The narration is found in multiple reliable sources with slight variations.",
|
|
"This is a widely transmitted hadith with consistent narration across sources.",
|
|
"The hadith is reported with authentic chain and acceptable wording.",
|
|
"This tradition appears in the primary sources with confirmed authenticity.",
|
|
"The narration demonstrates the scholarly consensus on this issue.",
|
|
"The hadith is part of the foundational traditions in this category.",
|
|
"This is one of the most frequently cited ahadith on this topic.",
|
|
]
|
|
|
|
hadis_references = {}
|
|
reference_counter = 0
|
|
|
|
for idx, hadis_id in enumerate(hadis_ids):
|
|
# Get or create Hadis object
|
|
try:
|
|
hadis = Hadis.objects.get(pk=hadis_id)
|
|
except Hadis.DoesNotExist:
|
|
self.stdout.write(
|
|
self.style.WARNING(f"⚠️ Hadis with ID {hadis_id} not found, skipping...")
|
|
)
|
|
continue
|
|
|
|
# Randomly assign 1-3 book references per hadith
|
|
num_refs = (idx % 3) + 1
|
|
selected_books = book_references_list[idx % len(book_references_list):(idx % len(book_references_list)) + num_refs]
|
|
|
|
for book_idx, book_ref in enumerate(selected_books):
|
|
hadis_ref, created = HadisReference.objects.get_or_create(
|
|
hadis=hadis,
|
|
book_reference=book_ref,
|
|
defaults={
|
|
'description': reference_descriptions[reference_counter % len(reference_descriptions)]
|
|
}
|
|
)
|
|
if created:
|
|
hadis_references[hadis_id] = hadis_ref
|
|
reference_counter += 1
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f"✓ Reference: Hadis {hadis_id} <- {book_ref.title}"
|
|
)
|
|
)
|
|
|
|
# Step 4: Add Reference Images
|
|
self.stdout.write(self.style.SUCCESS('\n🖼️ Adding Reference Images...'))
|
|
ref_images_added = self._add_reference_images(hadis_references)
|
|
self.stdout.write(f"✓ Added {ref_images_added} reference images")
|
|
|
|
# Step 5: Create Hadis In Collection
|
|
self.stdout.write(self.style.SUCCESS('\n📋 Adding Hadis to Collections...'))
|
|
|
|
collection_assignments = [
|
|
{
|
|
"collection_title": "Purification & Prayer",
|
|
"hadis_ids": [1800, 1801, 1802, 1803, 1804],
|
|
},
|
|
{
|
|
"collection_title": "Zakat & Charity",
|
|
"hadis_ids": [1805, 1806, 1807, 1808],
|
|
},
|
|
{
|
|
"collection_title": "Fasting & Ramadan",
|
|
"hadis_ids": [1809, 1810, 1811, 1812, 1813],
|
|
},
|
|
{
|
|
"collection_title": "Hajj & Umrah",
|
|
"hadis_ids": [1814, 1815, 1816, 1817],
|
|
},
|
|
{
|
|
"collection_title": "Ethics & Morality",
|
|
"hadis_ids": [1818, 1819, 1820, 1821, 1822, 1823],
|
|
},
|
|
{
|
|
"collection_title": "Knowledge & Learning",
|
|
"hadis_ids": [1824, 1825, 1826, 1827],
|
|
},
|
|
{
|
|
"collection_title": "Family & Relations",
|
|
"hadis_ids": [1828, 1829, 1830, 1831, 1832, 1833],
|
|
},
|
|
{
|
|
"collection_title": "Business & Trade",
|
|
"hadis_ids": [1834, 1835, 1836, 1837, 1838],
|
|
},
|
|
]
|
|
|
|
hadis_in_collection_count = 0
|
|
for assignment in collection_assignments:
|
|
collection = collections.get(assignment['collection_title'])
|
|
if not collection:
|
|
continue
|
|
|
|
for order, hadis_id in enumerate(assignment['hadis_ids']):
|
|
try:
|
|
hadis = Hadis.objects.get(pk=hadis_id)
|
|
hic, created = HadisInCollection.objects.get_or_create(
|
|
hadis=hadis,
|
|
collection=collection,
|
|
defaults={'order': order}
|
|
)
|
|
if created:
|
|
hadis_in_collection_count += 1
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f"✓ Added Hadis {hadis_id} to {collection.title} (Order {order})"
|
|
)
|
|
)
|
|
except Hadis.DoesNotExist:
|
|
pass
|
|
|
|
# Step 6: Create Hadis Corrections
|
|
self.stdout.write(self.style.SUCCESS('\n✏️ Creating Hadis Corrections...'))
|
|
|
|
corrections_data = [
|
|
{
|
|
"hadis_id": 1800,
|
|
"title": "Clarification on Wudu Sequence",
|
|
"description": "Some scholars differ on the exact sequence of washing body parts during ablution.",
|
|
"translation": [
|
|
{"lang": "en", "text": "The order of washing in wudu should follow the established practice."},
|
|
{"lang": "ar", "text": "ترتيب غسل الأعضاء في الوضوء يجب أن يتبع السنة المثبتة."}
|
|
],
|
|
},
|
|
{
|
|
"hadis_id": 1802,
|
|
"title": "Prayer Time Variations",
|
|
"description": "Different schools of thought have varying opinions on prayer times.",
|
|
"translation": [
|
|
{"lang": "en", "text": "Prayer times may vary slightly depending on geographical location."},
|
|
{"lang": "ar", "text": "أوقات الصلاة قد تختلف قليلاً حسب الموقع الجغرافي."}
|
|
],
|
|
},
|
|
{
|
|
"hadis_id": 1805,
|
|
"title": "Zakat Calculation Methods",
|
|
"description": "Various methods exist for calculating zakat on different types of wealth.",
|
|
"translation": [
|
|
{"lang": "en", "text": "The calculation of zakat follows specific rules for different assets."},
|
|
{"lang": "ar", "text": "حساب الزكاة يتبع قواعد محددة لأنواع مختلفة من الأموال."}
|
|
],
|
|
},
|
|
{
|
|
"hadis_id": 1810,
|
|
"title": "Fasting in Different Climates",
|
|
"description": "Scholars discuss fasting practices in regions with extreme daylight variations.",
|
|
"translation": [
|
|
{"lang": "en", "text": "Fasting guidelines adapt to extreme daylight conditions in certain regions."},
|
|
{"lang": "ar", "text": "تتكيف إرشادات الصيام مع ظروف الإضاءة الشديدة في بعض المناطق."}
|
|
],
|
|
},
|
|
{
|
|
"hadis_id": 1815,
|
|
"title": "Hajj Routes and Methods",
|
|
"description": "Multiple routes and methods for performing Hajj rituals are recognized.",
|
|
"translation": [
|
|
{"lang": "en", "text": "Different schools recognize various methods for performing Hajj rituals."},
|
|
{"lang": "ar", "text": "تعترف المذاهب المختلفة بطرق متعددة لأداء مناسك الحج."}
|
|
],
|
|
},
|
|
{
|
|
"hadis_id": 1820,
|
|
"title": "Ethical Conduct in Commerce",
|
|
"description": "Islamic principles of honesty and fairness in business transactions.",
|
|
"translation": [
|
|
{"lang": "en", "text": "Islamic business ethics emphasize honesty and mutual fairness."},
|
|
{"lang": "ar", "text": "تؤكد أخلاقيات الأعمال الإسلامية على الصدق والإنصاف المتبادل."}
|
|
],
|
|
},
|
|
{
|
|
"hadis_id": 1825,
|
|
"title": "Hadith Authentication Methods",
|
|
"description": "Scholars use various methodologies for authenticating hadith narrations.",
|
|
"translation": [
|
|
{"lang": "en", "text": "Hadith scholars employ rigorous methodology in authentication."},
|
|
{"lang": "ar", "text": "يستخدم علماء الحديث منهجية صارمة في التحقق من الصحة."}
|
|
],
|
|
},
|
|
{
|
|
"hadis_id": 1830,
|
|
"title": "Family Rights and Obligations",
|
|
"description": "The Islamic framework defines rights and responsibilities within families.",
|
|
"translation": [
|
|
{"lang": "en", "text": "Islam defines clear rights and obligations for family members."},
|
|
{"lang": "ar", "text": "يحدد الإسلام حقوقاً والتزامات واضحة لأفراد الأسرة."}
|
|
],
|
|
},
|
|
]
|
|
|
|
corrections_count = 0
|
|
for correction_data in corrections_data:
|
|
hadis_id = correction_data.pop('hadis_id')
|
|
try:
|
|
hadis = Hadis.objects.get(pk=hadis_id)
|
|
correction, created = HadisCorrection.objects.get_or_create(
|
|
hadis=hadis,
|
|
title=correction_data['title'],
|
|
defaults=correction_data
|
|
)
|
|
if created:
|
|
corrections_count += 1
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f"✓ Correction created: {correction_data['title']} for Hadis {hadis_id}"
|
|
)
|
|
)
|
|
except Hadis.DoesNotExist:
|
|
pass
|
|
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f'\n✓ Successfully seeded hadith data!'
|
|
)
|
|
)
|
|
self._print_summary(
|
|
collections,
|
|
hadis_in_collection_count,
|
|
len(hadis_references),
|
|
ref_images_added,
|
|
corrections_count
|
|
)
|
|
|
|
def _add_reference_images(self, hadis_references):
|
|
"""Add reference images from seeds/images folder"""
|
|
images_added = 0
|
|
ref_images = ['ref1.png', 'ref2.png', 'ref3.png', 'ref4.png']
|
|
image_counter = 0
|
|
|
|
for hadis_id, hadis_ref in hadis_references.items():
|
|
# Add 1-2 images per reference
|
|
num_images = (image_counter % 2) + 1
|
|
|
|
for img_idx in range(num_images):
|
|
image_name = ref_images[image_counter % len(ref_images)]
|
|
image_path = self._get_image_path(image_name)
|
|
|
|
if image_path and os.path.exists(image_path):
|
|
# Check if image already exists
|
|
existing_images_count = hadis_ref.images.count()
|
|
|
|
with open(image_path, 'rb') as img_file:
|
|
ref_image, created = ReferenceImage.objects.get_or_create(
|
|
reference=hadis_ref,
|
|
priority=existing_images_count + img_idx,
|
|
defaults={
|
|
'thumbnail': None
|
|
}
|
|
)
|
|
if created:
|
|
# Save the image file
|
|
ref_image.thumbnail.save(
|
|
image_name,
|
|
ContentFile(img_file.read()),
|
|
save=True
|
|
)
|
|
images_added += 1
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f"✓ Image added: {image_name} to Hadis {hadis_id} reference"
|
|
)
|
|
)
|
|
|
|
image_counter += 1
|
|
|
|
return images_added
|
|
|
|
def _get_image_path(self, image_name):
|
|
"""Find the image file for the given image name"""
|
|
possible_paths = [
|
|
Path('seeds/images') / image_name,
|
|
Path('seed_data/images') / image_name,
|
|
Path('static/images') / image_name,
|
|
Path('.') / 'seeds' / 'images' / image_name,
|
|
]
|
|
|
|
for path in possible_paths:
|
|
if path.exists():
|
|
return path
|
|
|
|
return None
|
|
|
|
def _print_summary(self, collections, hadis_in_collection_count, references_count, images_count, corrections_count):
|
|
"""Print a summary of created data"""
|
|
self.stdout.write("\n" + "="*70)
|
|
self.stdout.write(self.style.SUCCESS("HADITH DATABASE SUMMARY"))
|
|
self.stdout.write("="*70)
|
|
|
|
collections_count = HadisCollection.objects.count()
|
|
total_hadis_in_collection = HadisInCollection.objects.count()
|
|
total_references = HadisReference.objects.count()
|
|
total_ref_images = ReferenceImage.objects.count()
|
|
total_corrections = HadisCorrection.objects.count()
|
|
|
|
self.stdout.write(f"📚 Hadis Collections: {collections_count}")
|
|
self.stdout.write(f"📋 Hadis in Collections: {total_hadis_in_collection}")
|
|
self.stdout.write(f"🔗 Hadis References: {total_references}")
|
|
self.stdout.write(f"🖼️ Reference Images: {total_ref_images}")
|
|
self.stdout.write(f"✏️ Hadis Corrections: {total_corrections}")
|
|
|
|
self.stdout.write("\n" + "="*70)
|
|
self.stdout.write(self.style.WARNING("Collections Created:"))
|
|
self.stdout.write("="*70)
|
|
for collection_title in list(collections.keys()):
|
|
hadis_count = HadisInCollection.objects.filter(
|
|
collection__title=collection_title
|
|
).count()
|
|
self.stdout.write(f" • {collection_title} ({hadis_count} ahadith)")
|
|
|
|
self.stdout.write("="*70 + "\n")
|