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.
 
 
 
 
 

265 lines
13 KiB

import os
import random
import urllib.request
from django.core.management.base import BaseCommand
from django.db import transaction
from django.core.files.base import ContentFile
from apps.hadis.models import (
BookReference,
BookAuthor,
BookEdition,
BookVolume,
BookResearcher,
BookEditor,
)
class Command(BaseCommand):
help = 'Generates randomized Editions and Volumes (with sample cover image and PDF file) for all BookReferences.'
def add_arguments(self, parser):
parser.add_argument(
'--clear',
action='store_true',
default=True,
help='Clear existing BookEditions and BookVolumes before generating (default: True)',
)
parser.add_argument(
'--keep-existing',
action='store_true',
help='Do not clear existing data, only add/modify',
)
def _fetch_sample_assets(self):
"""
Downloads a lightweight Islamic cover image and sample PDF from the web.
Falls back to generated placeholder bytes if network request fails.
"""
self.stdout.write("Downloading sample Islamic book image and sample PDF...")
image_url = "https://images.unsplash.com/photo-1609599006353-e629aaabfeae?w=500&auto=format&fit=crop&q=80"
image_bytes = None
try:
req = urllib.request.Request(image_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'})
with urllib.request.urlopen(req, timeout=15) as resp:
image_bytes = resp.read()
self.stdout.write(self.style.SUCCESS(f"Downloaded sample cover image ({len(image_bytes)} bytes)."))
except Exception as e:
self.stdout.write(self.style.WARNING(f"Failed to download image ({e}), generating a local fallback image..."))
from PIL import Image, ImageDraw
import io
img = Image.new('RGB', (400, 600), color='#1e293b')
draw = ImageDraw.Draw(img)
draw.rectangle([20, 20, 380, 580], outline='#e2e8f0', width=3)
buf = io.BytesIO()
img.save(buf, format='JPEG')
image_bytes = buf.getvalue()
pdf_url = "https://raw.githubusercontent.com/mozilla/pdf.js/master/examples/learning/helloworld.pdf"
pdf_bytes = None
try:
req = urllib.request.Request(pdf_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'})
with urllib.request.urlopen(req, timeout=15) as resp:
pdf_bytes = resp.read()
self.stdout.write(self.style.SUCCESS(f"Downloaded sample PDF document ({len(pdf_bytes)} bytes)."))
except Exception as e:
self.stdout.write(self.style.WARNING(f"Failed to download PDF ({e}), generating a fallback PDF..."))
from reportlab.pdfgen import canvas
import io
buf = io.BytesIO()
p = canvas.Canvas(buf)
p.drawString(100, 750, "Sample Islamic Hadith Reference Document")
p.drawString(100, 720, "This is a lightweight sample volume file.")
p.showPage()
p.save()
pdf_bytes = buf.getvalue()
return image_bytes, pdf_bytes
def handle(self, *args, **options):
clear_existing = not options.get('keep_existing', False)
references = list(BookReference.objects.all())
authors = list(BookAuthor.objects.all())
if not references:
self.stdout.write(self.style.ERROR("No BookReference found in the database."))
return
self.stdout.write(f"Found {len(references)} BookReferences and {len(authors)} BookAuthors.")
if clear_existing:
self.stdout.write(self.style.WARNING("Clearing existing BookEditions and BookVolumes..."))
BookVolume.objects.all().delete()
BookEdition.objects.all().delete()
BookResearcher.objects.all().delete()
BookEditor.objects.all().delete()
# Download or prepare sample assets
image_bytes, pdf_bytes = self._fetch_sample_assets()
# Publishers pool
publishers_pool = [
[
{"language_code": "fa", "text": "دار الحديث"},
{"language_code": "ar", "text": "دار الحديث للطباعة والنشر"},
{"language_code": "en", "text": "Dar al-Hadith Publications"},
],
[
{"language_code": "fa", "text": "مؤسسة آل البيت (ع) لإحياء التراث"},
{"language_code": "ar", "text": "مؤسسة آل البيت عليهم السلام لإحياء التراث"},
{"language_code": "en", "text": "Aal al-Bayt Institute for Heritage Revival"},
],
[
{"language_code": "fa", "text": "دار الكتب الإسلامية"},
{"language_code": "ar", "text": "دار الكتب الإسلامية"},
{"language_code": "en", "text": "Dar al-Kutub al-Islamiyya"},
],
[
{"language_code": "fa", "text": "منشورات الشريف الرضي"},
{"language_code": "ar", "text": "منشورات الشريف الرضي"},
{"language_code": "en", "text": "Al-Sharif al-Razi Publications"},
],
[
{"language_code": "fa", "text": "مؤسسة النشر الإسلامي"},
{"language_code": "ar", "text": "مؤسسة النشر الإسلامي التابعة لجماعة المدرسين"},
{"language_code": "en", "text": "Islamic Publishing Foundation"},
],
[
{"language_code": "fa", "text": "مؤسسة البلاغ"},
{"language_code": "ar", "text": "مؤسسة البلاغ للطباعة والنشر والتوزيع"},
{"language_code": "en", "text": "Al-Balagh Foundation"},
],
]
cities_pool = [
[{"language_code": "fa", "text": "قم"}, {"language_code": "ar", "text": "قم المقدسة"}, {"language_code": "en", "text": "Qom"}],
[{"language_code": "fa", "text": "بیروت"}, {"language_code": "ar", "text": "بيروت"}, {"language_code": "en", "text": "Beirut"}],
[{"language_code": "fa", "text": "نجف"}, {"language_code": "ar", "text": "النجف الأشرف"}, {"language_code": "en", "text": "Najaf"}],
[{"language_code": "fa", "text": "تهران"}, {"language_code": "ar", "text": "طهران"}, {"language_code": "en", "text": "Tehran"}],
[{"language_code": "fa", "text": "مشهد"}, {"language_code": "ar", "text": "مشهد المقدسة"}, {"language_code": "en", "text": "Mashhad"}],
]
countries_pool = [
[{"language_code": "fa", "text": "ایران"}, {"language_code": "ar", "text": "إيران"}, {"language_code": "en", "text": "Iran"}],
[{"language_code": "fa", "text": "لبنان"}, {"language_code": "ar", "text": "لبنان"}, {"language_code": "en", "text": "Lebanon"}],
[{"language_code": "fa", "text": "عراق"}, {"language_code": "ar", "text": "العراق"}, {"language_code": "en", "text": "Iraq"}],
]
edition_names = ["چاپ اول", "چاپ دوم", "چاپ سوم", "طبعة ثانية منقحة", "طبعة أولى محققة", "First Revised Edition", "Second Edition"]
years_pool = ["1418 هـ.ق", "1422 هـ.ق", "1429 هـ.ق", "1436 هـ.ق", "1441 هـ.ق", "1385 ش", "1392 ش", "1398 ش", "1402 ش"]
total_editions_created = 0
total_volumes_created = 0
total_researchers_created = 0
total_editors_created = 0
self.stdout.write("Generating Editions and Volumes for BookReferences...")
with transaction.atomic():
for ref in references:
# Random choice: whether this reference has editions or only direct volumes
has_editions = random.choice([True, False])
ref.has_editions = has_editions
ref.save(update_fields=['has_editions'])
if has_editions:
num_editions = random.randint(1, 3)
for ed_idx in range(1, num_editions + 1):
num_volumes = random.randint(3, 5)
pub = random.choice(publishers_pool)
city = random.choice(cities_pool)
country = random.choice(countries_pool)
ed_num = random.choice(edition_names)
year = random.choice(years_pool)
isbn = f"978-964-{random.randint(100, 999)}-{random.randint(10, 99)}-{random.randint(0, 9)}"
edition = BookEdition.objects.create(
book_reference=ref,
publisher=pub,
city_of_publication=city,
country_of_publication=country,
edition_number=f"{ed_num} ({ed_idx})",
year_of_publication=year,
number_of_volumes=num_volumes,
isbn=isbn,
notes=[
{"language_code": "fa", "text": f"نسخه معتبر تصحیح شده با مقابله با نسخ خطی {ed_idx}"},
{"language_code": "en", "text": f"Verified critical edition compared against manuscripts {ed_idx}"}
],
source_url=f"https://lib.eshia.ir/{ref.id}/{edition_names[0]}"
)
total_editions_created += 1
# Assign random researchers and editors from existing authors
if authors:
sample_researchers = random.sample(authors, min(len(authors), random.randint(1, 2)))
for author in sample_researchers:
BookResearcher.objects.create(
book_edition=edition,
author=author
)
total_researchers_created += 1
sample_editors = random.sample(authors, min(len(authors), random.randint(1, 2)))
for author in sample_editors:
BookEditor.objects.create(
book_edition=edition,
author=author
)
total_editors_created += 1
# Create 3 to 5 volumes for this edition
for vol_idx in range(1, num_volumes + 1):
vol = BookVolume(
book_reference=ref,
edition=edition,
title=f"جلد {vol_idx}",
)
vol.image.save(
f"ref_{ref.id}_ed_{edition.id}_vol_{vol_idx}_cover.jpg",
ContentFile(image_bytes),
save=False
)
vol.file.save(
f"ref_{ref.id}_ed_{edition.id}_vol_{vol_idx}.pdf",
ContentFile(pdf_bytes),
save=False
)
vol.save()
total_volumes_created += 1
else:
# Direct volumes without editions
num_volumes = random.randint(3, 5)
for vol_idx in range(1, num_volumes + 1):
vol = BookVolume(
book_reference=ref,
edition=None,
title=f"جلد {vol_idx}",
)
vol.image.save(
f"ref_{ref.id}_vol_{vol_idx}_cover.jpg",
ContentFile(image_bytes),
save=False
)
vol.file.save(
f"ref_{ref.id}_vol_{vol_idx}.pdf",
ContentFile(pdf_bytes),
save=False
)
vol.save()
total_volumes_created += 1
self.stdout.write(
self.style.SUCCESS(
f"\n--- Seeding Completed Successfully ---\n"
f"Processed {len(references)} BookReferences:\n"
f" - Total BookEditions created: {total_editions_created}\n"
f" - Total BookVolumes created: {total_volumes_created}\n"
f" - Total Researchers assigned: {total_researchers_created}\n"
f" - Total Editors assigned: {total_editors_created}\n"
f" - Cover image & PDF attached to all volumes."
)
)