Browse Source

feat: add management command to refresh share links and script to validate link consistency

master
Mohsen Taba 2 months ago
parent
commit
6f51d2d6f9
  1. 27
      apps/hadis/management/commands/refresh_share_links.py
  2. 97
      validate_share_links.py

27
apps/hadis/management/commands/refresh_share_links.py

@ -1,11 +1,20 @@
from django.core.management.base import BaseCommand 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 from apps.hadis.models import Hadis, HadisCorrection, TransmitterOriginalText
class Command(BaseCommand): 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): def handle(self, *args, **options):
missing_only = options.get('missing_only')
models_to_refresh = [ models_to_refresh = [
(Hadis, "Hadis"), (Hadis, "Hadis"),
(HadisCorrection, "Hadis Correction"), (HadisCorrection, "Hadis Correction"),
@ -15,11 +24,17 @@ class Command(BaseCommand):
for model_class, name in models_to_refresh: for model_class, name in models_to_refresh:
self.stdout.write(self.style.WARNING(f'--- Processing {name} ---')) self.stdout.write(self.style.WARNING(f'--- Processing {name} ---'))
if missing_only:
instances = model_class.objects.filter(
models.Q(share_link__isnull=True) | models.Q(share_link='')
)
else:
instances = model_class.objects.all() instances = model_class.objects.all()
count = instances.count() count = instances.count()
if count == 0: if count == 0:
self.stdout.write(f"No {name} instances found.")
self.stdout.write(f"No {name} instances found to process.")
continue continue
processed = 0 processed = 0
@ -27,7 +42,7 @@ class Command(BaseCommand):
with transaction.atomic(): with transaction.atomic():
for instance in instances: for instance in instances:
try: try:
# This triggers your updated .save() logic
# Re-saving triggers the updated .save() logic which regenerates the share_link
instance.save() instance.save()
processed += 1 processed += 1
@ -39,6 +54,6 @@ class Command(BaseCommand):
f"Error saving {name} ID {instance.id}: {str(e)}" 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 ---'))
self.stdout.write(self.style.SUCCESS('--- All models processed successfully ---'))

97
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()
Loading…
Cancel
Save