diff --git a/apps/hadis/management/commands/refresh_share_links.py b/apps/hadis/management/commands/refresh_share_links.py index 8a6cf27..eb80cab 100644 --- a/apps/hadis/management/commands/refresh_share_links.py +++ b/apps/hadis/management/commands/refresh_share_links.py @@ -1,11 +1,20 @@ from django.core.management.base import BaseCommand -from django.db import transaction +from django.db import transaction, models from apps.hadis.models import Hadis, HadisCorrection, TransmitterOriginalText class Command(BaseCommand): - help = 'Refreshes slugs and share_links by re-saving all existing instances of Hadis models.' + help = 'Refreshes slugs and share_links by re-saving all existing instances of models that store share_links in the database.' + + def add_arguments(self, parser): + parser.add_argument( + '--missing-only', + action='store_true', + help='Only update share_links that are empty or null', + ) def handle(self, *args, **options): + missing_only = options.get('missing_only') + models_to_refresh = [ (Hadis, "Hadis"), (HadisCorrection, "Hadis Correction"), @@ -15,11 +24,17 @@ class Command(BaseCommand): for model_class, name in models_to_refresh: self.stdout.write(self.style.WARNING(f'--- Processing {name} ---')) - instances = model_class.objects.all() + if missing_only: + instances = model_class.objects.filter( + models.Q(share_link__isnull=True) | models.Q(share_link='') + ) + else: + instances = model_class.objects.all() + count = instances.count() if count == 0: - self.stdout.write(f"No {name} instances found.") + self.stdout.write(f"No {name} instances found to process.") continue processed = 0 @@ -27,7 +42,7 @@ class Command(BaseCommand): with transaction.atomic(): for instance in instances: try: - # This triggers your updated .save() logic + # Re-saving triggers the updated .save() logic which regenerates the share_link instance.save() processed += 1 @@ -39,6 +54,6 @@ class Command(BaseCommand): f"Error saving {name} ID {instance.id}: {str(e)}" )) - self.stdout.write(self.style.SUCCESS(f'Successfully refreshed {processed} {name} instances.')) + self.stdout.write(self.style.SUCCESS(f'Successfully processed {processed} {name} instances.')) - self.stdout.write(self.style.SUCCESS('--- All models refreshed successfully ---')) \ No newline at end of file + self.stdout.write(self.style.SUCCESS('--- All models processed successfully ---')) \ No newline at end of file diff --git a/validate_share_links.py b/validate_share_links.py new file mode 100644 index 0000000..adc2a46 --- /dev/null +++ b/validate_share_links.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +import os +import sys +import django +from django.conf import settings + +# Setup Django +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.base') +django.setup() + +from apps.hadis.models import Hadis, HadisCategory, Transmitters, BookReference, TransmitterOriginalText +from apps.article.models import Article +from apps.podcast.models import Podcast +from apps.video.models import Video +from apps.library.models import Book + +def check_link(name, link, expected_pattern): + if not link: + print(f"โŒ {name}: Link is missing") + return False + + # Simple pattern check (standard doesn't specify exact origin, but backend uses settings.DOVODI_DOMAIN) + origin = settings.DOVODI_DOMAIN + expected = expected_pattern.format(origin=origin) + + if link.startswith(expected): + print(f"โœ… {name}: {link}") + return True + else: + print(f"โŒ {name}: Got {link}, expected pattern starting with {expected}") + return False + +def main(): + print("๐Ÿงช Validating Standardized Share Links") + print("=" * 60) + + success = True + + # 1. Hadith + h = Hadis.objects.filter(slug__isnull=False).first() + if h: + if not check_link("Hadith", h.share_link, "{origin}/arguments/hadith/"): + success = False + + # 2. Category + c = HadisCategory.objects.filter(slug__isnull=False).first() + if c: + if not check_link("Category", c.share_link, "{origin}/arguments/category/"): + success = False + if c.xmind_file: + if not check_link("Mind Map", c.xmind_share_link, "{origin}/xmind/"): + success = False + + # 3. Narrator (Transmitters) + t = Transmitters.objects.filter(slug__isnull=False).first() + if t: + if not check_link("Narrator", t.share_link, "{origin}/arguments/narrators/"): + success = False + + # 4. Source (BookReference) + br = BookReference.objects.filter(slug__isnull=False).first() + if br: + if not check_link("Source", br.share_link, "{origin}/arguments/sources/"): + success = False + + # 5. Article + a = Article.objects.filter(slug__isnull=False).first() + if a: + if not check_link("Article", a.share_link, "{origin}/articles/"): + success = False + + # 6. Podcast + p = Podcast.objects.filter(slug__isnull=False).first() + if p: + if not check_link("Podcast", p.share_link, "{origin}/podcast/"): + success = False + + # 7. Video + v = Video.objects.filter(slug__isnull=False).first() + if v: + if not check_link("Video", v.share_link, "{origin}/videos/"): + success = False + + # 8. Library Book + lb = Book.objects.filter(slug__isnull=False).first() + if lb: + if not check_link("Library Book", lb.share_link, "{origin}/library/"): + success = False + + print("=" * 60) + if success: + print("๐ŸŽ‰ ALL CHECKS PASSED!") + else: + print("โš ๏ธ SOME CHECKS FAILED. Please review the output above.") + +if __name__ == "__main__": + main()