Browse Source

fixed referene image script

master
Mohsen Taba 4 months ago
parent
commit
69e80ada37
  1. 6
      apps/hadis/apps.py
  2. 144
      apps/hadis/management/commands/populate_refrence_images.py
  3. 2
      entrypoint.sh

6
apps/hadis/apps.py

@ -4,6 +4,6 @@ from django.apps import AppConfig
class HadisConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.hadis'
def ready(self):
# Import the signals module when the app starts
import apps.hadis.signals
# def ready(self):
# # Import the signals module when the app starts
# # import apps.hadis.signals

144
apps/hadis/management/commands/populate_refrence_images.py

@ -2,22 +2,21 @@ import os
import random
from django.core.management.base import BaseCommand
from django.core.files import File
from django.core.files.base import ContentFile
from django.conf import settings
from django.db import transaction
# REMEMBER: Change 'your_app' to your actual app name
from apps.hadis.models.hadis import Hadis, HadisReference, ReferenceImage
from apps.hadis.models.reference import BookReference
class Command(BaseCommand):
help = 'Wipes old reference data and seeds new HadisReference and ReferenceImages'
help = 'Seeds HadisReferences ensuring every Book has 2+ hadiths AND every Hadith has 1+ reference.'
def handle(self, *args, **kwargs):
self.stdout.write(self.style.WARNING('--- Starting Cleanup ---'))
# 1. DELETE PREVIOUS DATA
# We delete HadisReference. Because of on_delete=models.CASCADE in ReferenceImage,
# deleting the reference will automatically delete the associated images.
# However, we can delete both explicitly to be sure and show counts.
deleted_imgs_count, _ = ReferenceImage.objects.all().delete()
deleted_refs_count, _ = HadisReference.objects.all().delete()
@ -25,69 +24,110 @@ class Command(BaseCommand):
self.stdout.write(self.style.SUCCESS(f'Deleted {deleted_refs_count} old HadisReferences.'))
self.stdout.write('------------------------')
# 2. Setup Paths for Seeding
base_image_path = os.path.join(settings.BASE_DIR, 'seeds', 'images')
# We look for ref1.png, ref2.png, ref3.png, ref4.png
image_files = [f'ref{i}.png' for i in range(1, 5)]
# 2. Setup Paths
self.base_image_path = os.path.join(settings.BASE_DIR, 'seeds', 'images')
self.image_files = [f'ref{i}.png' for i in range(1, 5)]
# Verify images exist locally before starting
for img_name in image_files:
full_path = os.path.join(base_image_path, img_name)
# Verify images
for img_name in self.image_files:
full_path = os.path.join(self.base_image_path, img_name)
if not os.path.exists(full_path):
self.stdout.write(self.style.ERROR(f'CRITICAL ERROR: Image not found at {full_path}'))
return
# 3. Fetch Parents
# 3. Fetch Data
books = list(BookReference.objects.all())
hadiths = list(Hadis.objects.all())
if len(hadiths) < 2:
self.stdout.write(self.style.ERROR('Not enough Hadiths in DB (need at least 2).'))
return
if not books:
self.stdout.write(self.style.ERROR('No BookReferences found in DB.'))
if not books or not hadiths:
self.stdout.write(self.style.ERROR('Missing Books or Hadiths in DB.'))
return
self.stdout.write('--- Starting Seeding ---')
counter_refs = 0
counter_imgs = 0
self.counter_refs = 0
self.counter_imgs = 0
# Track which Hadith IDs have been covered
covered_hadith_ids = set()
# 4. Iterate Books (Constraint 1: Each book must relate to at least 2 hadith)
# ==========================================
# PHASE 1: Satisfy Book Constraint
# "Each book must relate to at least 2 hadith"
# ==========================================
self.stdout.write("Phase 1: Linking Books to Hadiths...")
for book in books:
# Pick 2 random hadiths for this book
selected_hadiths = random.sample(hadiths, 2)
# We use distinct logic if we want to ensure we don't pick the same one twice for one book
selected_hadiths = random.sample(hadiths, k=min(len(hadiths), 2))
for hadis_obj in selected_hadiths:
# Create the Link (HadisReference)
hadis_ref = HadisReference.objects.create(
hadis=hadis_obj,
book_reference=book,
description=[
{'language_code': 'en', 'text': f'Reference for {book.title[0].get("text", "Book")} - Hadith {hadis_obj.number}'},
{'language_code': 'ar', 'text': 'وصف مرجعي'}
]
)
counter_refs += 1
# 5. Connect Images (Constraint 2: Each hadith ref must have 2 images)
# We pick 2 random images from our list of 4
selected_images = random.sample(image_files, 2)
for priority_index, img_name in enumerate(selected_images):
img_path = os.path.join(base_image_path, img_name)
with open(img_path, 'rb') as f:
# Create ReferenceImage
ref_img = ReferenceImage(
reference=hadis_ref,
priority=priority_index # 0 and 1
)
# Save file to the ImageField
ref_img.thumbnail.save(img_name, File(f), save=True)
counter_imgs += 1
self._create_reference_chain(hadis_obj, book)
covered_hadith_ids.add(hadis_obj.id)
# ==========================================
# PHASE 2: Satisfy Hadith Constraint
# "Each hadith must have a hadith reference object"
# ==========================================
self.stdout.write("Phase 2: Checking for orphan Hadiths...")
for hadis_obj in hadiths:
if hadis_obj.id not in covered_hadith_ids:
# This hadith was skipped in Phase 1.
# We must assign it to a Book (Reference).
# Pick a random book to associate with
random_book = random.choice(books)
self._create_reference_chain(hadis_obj, random_book)
covered_hadith_ids.add(hadis_obj.id)
self.stdout.write(self.style.SUCCESS(
f'DONE: Created {counter_refs} HadisReferences and {counter_imgs} ReferenceImages.'
))
f'DONE: Created {self.counter_refs} HadisReferences (covering {len(covered_hadith_ids)} Hadiths) and {self.counter_imgs} Images.'
))
def _create_reference_chain(self, hadis_obj, book_obj):
"""
Helper to create the Reference and its Images
"""
# Create the HadisReference
hadis_ref = HadisReference.objects.create(
hadis=hadis_obj,
book_reference=book_obj,
description=[
{'language_code': 'en', 'text': f'Reference for {book_obj.title[0].get("text", "Book")} - Hadith {hadis_obj.number}'},
{'language_code': 'ar', 'text': 'وصف مرجعي'}
]
)
self.counter_refs += 1
# Create Images for this Reference
self._create_images_for_ref(hadis_ref)
def _create_images_for_ref(self, hadis_ref):
"""
Helper to create 2 images for a specific HadisReference
"""
selected_images = random.sample(self.image_files, 2)
for priority_index, img_name in enumerate(selected_images):
img_path = os.path.join(self.base_image_path, img_name)
# Read file safely
with open(img_path, 'rb') as f:
file_content = f.read()
ref_img = ReferenceImage(
reference=hadis_ref,
priority=priority_index
)
# Assign content without auto-saving
ref_img.thumbnail.save(img_name, ContentFile(file_content), save=False)
try:
# Explicit save to handle your custom model logic / signals
ref_img.save()
self.counter_imgs += 1
except Exception as e:
self.stdout.write(self.style.ERROR(f"Failed to save image {img_name}: {e}"))

2
entrypoint.sh

@ -7,6 +7,6 @@ python manage.py collectstatic --noinput
# python manage.py populate_books
# python manage.py populate_book_reference
python manage.py populate_reference_images
python manage.py populate_refrence_images
exec "$@"
Loading…
Cancel
Save