diff --git a/Dockerfile.prod b/Dockerfile.prod index d374716..8110da5 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -44,11 +44,11 @@ RUN pip install --upgrade pip #RUN python -m pip install Pillow COPY ./requirements.txt . -COPY .env.prod .env RUN --mount=type=cache,target=/root/.cache pip install -r requirements.txt # copy entrypoint.sh +COPY .env.prod .env COPY ./entrypoint.sh . RUN sed -i 's/\r$//g' /usr/src/app/entrypoint.sh RUN chmod +x /usr/src/app/entrypoint.sh diff --git a/apps/hadis/management/commands/populate_narrator_links.py b/apps/hadis/management/commands/populate_narrator_links.py new file mode 100644 index 0000000..98033a7 --- /dev/null +++ b/apps/hadis/management/commands/populate_narrator_links.py @@ -0,0 +1,32 @@ +# backend/apps/hadis/management/commands/populate_narrator_links.py + +from django.core.management.base import BaseCommand +from apps.hadis.models import HadisCorrection, HadisInterpretation + +class Command(BaseCommand): + help = 'Populates the default narrator and links for all existing Corrections and Interpretations.' + + def handle(self, *args, **options): + self.stdout.write(self.style.WARNING("Updating default values for narrator and links...")) + + default_narrator = "زُرارَةُ بْنُ أَعْيَنَ الشَّيبانِيّ" + default_links = [ + {"title": "Первая ссылка Первая ссылка ссылкассы...", "link": "google.com"}, + {"title": "Первая ссылка.", "link": "google.com"}, + {"title": "Первая ссылка.", "link": "google.com"} + ] + + # آپدیت تمام رکوردهای جدول تصحیحات + corr_count = HadisCorrection.objects.all().update( + narrator=default_narrator, + links=default_links + ) + + # آپدیت تمام رکوردهای جدول تفاسیر + interp_count = HadisInterpretation.objects.all().update( + narrator=default_narrator, + links=default_links + ) + + self.stdout.write(self.style.SUCCESS(f"✅ Successfully updated {corr_count} HadisCorrections!")) + self.stdout.write(self.style.SUCCESS(f"✅ Successfully updated {interp_count} HadisInterpretations!")) \ No newline at end of file diff --git a/apps/hadis/management/commands/seed_interpretation_books.py b/apps/hadis/management/commands/seed_interpretation_books.py new file mode 100644 index 0000000..cf496cd --- /dev/null +++ b/apps/hadis/management/commands/seed_interpretation_books.py @@ -0,0 +1,53 @@ +# backend/apps/hadis/management/commands/seed_interpretation_books.py + +from django.core.management.base import BaseCommand +from django.db import transaction +from apps.hadis.models import HadisInterpretation, InterpretationReference, BookReference + +class Command(BaseCommand): + help = 'Assigns a default BookReference to HadisInterpretations that lack one.' + + def handle(self, *args, **options): + self.stdout.write(self.style.WARNING("Scanning for interpretations without book references...")) + + # پیدا کردن تفسیرهایی که هیچ رفرنسی ندارند + interpretations_without_book = HadisInterpretation.objects.filter(references__isnull=True) + count = interpretations_without_book.count() + + if count == 0: + self.stdout.write(self.style.SUCCESS("✅ All interpretations already have a book reference.")) + return + + # پیدا کردن اولین کتاب موجود در دیتابیس برای اتصال + book = BookReference.objects.first() + + # اگر هیچ کتابی در سیستم ثبت نشده بود، یک کتاب پیش‌فرض می‌سازیم + if not book: + import time + book = BookReference.objects.create( + title=[{"language_code": "en", "text": "Default Source Book"}], + slug=f"default-book-{int(time.time())}" + ) + self.stdout.write(self.style.WARNING("No BookReference found. Created a default dummy book.")) + + self.stdout.write(self.style.WARNING(f"Linking {count} interpretations to book ID: {book.id}...")) + + new_refs = [] + for interp in interpretations_without_book: + new_refs.append( + InterpretationReference( + interpretation=interp, + book_reference=book, + volume="", + pages="", + address="" + ) + ) + + # ساخت گروهی در دیتابیس + with transaction.atomic(): + InterpretationReference.objects.bulk_create(new_refs, batch_size=500) + + self.stdout.write( + self.style.SUCCESS(f"🎉 Successfully linked {len(new_refs)} interpretations to the book!") + ) \ No newline at end of file diff --git a/apps/hadis/migrations/0023_hadiscorrection_narrator_and_more.py b/apps/hadis/migrations/0023_hadiscorrection_narrator_and_more.py new file mode 100644 index 0000000..b1bfde4 --- /dev/null +++ b/apps/hadis/migrations/0023_hadiscorrection_narrator_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.12 on 2026-06-27 10:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hadis', '0022_hadisinterpretation_slug'), + ] + + operations = [ + migrations.AddField( + model_name='hadiscorrection', + name='narrator', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Narrator'), + ), + migrations.AddField( + model_name='hadisinterpretation', + name='narrator', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Narrator'), + ), + ] diff --git a/apps/hadis/migrations/0024_hadiscorrection_links_hadisinterpretation_links.py b/apps/hadis/migrations/0024_hadiscorrection_links_hadisinterpretation_links.py new file mode 100644 index 0000000..b65a90a --- /dev/null +++ b/apps/hadis/migrations/0024_hadiscorrection_links_hadisinterpretation_links.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.12 on 2026-06-27 10:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hadis', '0023_hadiscorrection_narrator_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='hadiscorrection', + name='links', + field=models.JSONField(blank=True, default=dict, null=True, verbose_name='links'), + ), + migrations.AddField( + model_name='hadisinterpretation', + name='links', + field=models.JSONField(blank=True, default=dict, null=True, verbose_name='links'), + ), + ] diff --git a/apps/hadis/models/hadis.py b/apps/hadis/models/hadis.py index 5dd99ac..ecdbd05 100644 --- a/apps/hadis/models/hadis.py +++ b/apps/hadis/models/hadis.py @@ -494,6 +494,8 @@ class HadisCorrection(models.Model): title = models.JSONField(default = list , verbose_name=_('Title')) slug = models.SlugField(max_length=255, verbose_name=_('slug'), blank=True,unique=True) legacy_id = models.CharField(max_length=255, unique=True, null=True, blank=True, db_index=True) + narrator = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('Narrator')) + links = models.JSONField(verbose_name=_('links'), null=True, blank=True, default=dict) text = models.TextField(verbose_name=_('Original Text'), default="", blank=True) translation = models.JSONField(verbose_name=_("translation"), default=list) priority = models.IntegerField(default=0, verbose_name=_('priority')) @@ -570,6 +572,8 @@ class HadisInterpretation(models.Model): category = models.ForeignKey('HadisCategory', on_delete=models.CASCADE, related_name='interpretations', verbose_name=_('Category')) slug = models.SlugField(max_length=255, verbose_name=_('slug'), blank=True, db_index=True) # 👈 فیلد جدید legacy_id = models.CharField(max_length=255, unique=True, null=True, blank=True, db_index=True) + narrator = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('Narrator')) + links = models.JSONField(verbose_name=_('links'), null=True, blank=True, default=dict) title = models.JSONField(default=list, verbose_name=_('Title')) text = models.TextField(verbose_name=_('Original Text')) diff --git a/apps/hadis/serializers/hadis.py b/apps/hadis/serializers/hadis.py index 0bbf5e3..b5fe16d 100644 --- a/apps/hadis/serializers/hadis.py +++ b/apps/hadis/serializers/hadis.py @@ -781,7 +781,7 @@ class HadisCorrectionSerializer(serializers.ModelSerializer): bookmark = serializers.SerializerMethodField() class Meta: model = HadisCorrection - fields = ['id', 'title','slug','description', 'translation','share_link','bookmark'] + fields = ['id', 'title','slug','narrator','description', 'translation','share_link','bookmark'] def get_description(self, obj): request = self.context.get('request') return get_localized_correction_text(obj.text, request=request) @@ -1050,7 +1050,7 @@ class HadisCorrectionDetailSerializer(serializers.ModelSerializer): class Meta: model = HadisCorrection - fields = ['id', 'title', 'slug', 'description', 'translation', 'share_link', 'hadis_info', 'references'] + fields = ['id', 'title', 'slug', 'narrator', 'description', 'translation', 'share_link', 'hadis_info', 'references'] def get_description(self, obj): return get_localized_correction_text(obj.text, request=self.context.get('request')) @@ -1067,7 +1067,7 @@ class HadisInterpretationDetailSerializer(serializers.ModelSerializer): class Meta: model = HadisInterpretation - fields = ['id', 'title', 'text', 'translation', 'priority', 'category_info', 'references'] + fields = ['id', 'title', 'slug', 'narrator', 'text', 'translation', 'category_info', 'references'] def get_category_info(self, obj): return {