from django.core.management.base import BaseCommand from django.core.files.base import ContentFile from django.utils.text import slugify from hub.services.models import ( ImageLibrary, Service, CloudProvider, ConsultingPartner, Article, ) import os import shutil class Command(BaseCommand): help = "Migrate existing images to the Image Library" def add_arguments(self, parser): parser.add_argument( "--dry-run", action="store_true", help="Show what would be migrated without actually doing it", ) parser.add_argument( "--force", action="store_true", help="Force migration even if images already exist in library", ) def handle(self, *args, **options): """ Main command handler to migrate existing images to the library. """ dry_run = options["dry_run"] force = options["force"] self.stdout.write( self.style.SUCCESS( f'Starting image migration {"(DRY RUN)" if dry_run else ""}' ) ) # Migrate different types of images self.migrate_service_logos(dry_run, force) self.migrate_cloud_provider_logos(dry_run, force) self.migrate_partner_logos(dry_run, force) self.migrate_article_images(dry_run, force) self.stdout.write( self.style.SUCCESS( f'Image migration completed {"(DRY RUN)" if dry_run else ""}' ) ) def migrate_service_logos(self, dry_run, force): """ Migrate service logos to the image library. """ self.stdout.write("Migrating service logos...") services = Service.objects.filter(logo__isnull=False).exclude(logo="") for service in services: if not service.logo: continue # Check if image already exists in library existing_image = ImageLibrary.objects.filter( name=f"{service.name} Logo" ).first() if existing_image and not force: self.stdout.write( self.style.WARNING( f" - Skipping {service.name} logo (already exists)" ) ) continue if dry_run: self.stdout.write( self.style.SUCCESS(f" - Would migrate: {service.name} logo") ) continue # Create image library entry image_lib = ImageLibrary( name=f"{service.name} Logo", slug=slugify(f"{service.name}-logo"), description=f"Logo for {service.name} service", alt_text=f"{service.name} logo", category="logo", tags=f"service, logo, {service.name.lower()}", ) # Copy the image file if service.logo and os.path.exists(service.logo.path): with open(service.logo.path, "rb") as f: image_lib.image.save( os.path.basename(service.logo.name), ContentFile(f.read()), save=True, ) self.stdout.write( self.style.SUCCESS(f" - Migrated: {service.name} logo") ) else: self.stdout.write( self.style.ERROR( f" - Failed to migrate: {service.name} logo (file not found)" ) ) def migrate_cloud_provider_logos(self, dry_run, force): """ Migrate cloud provider logos to the image library. """ self.stdout.write("Migrating cloud provider logos...") providers = CloudProvider.objects.filter(logo__isnull=False).exclude(logo="") for provider in providers: if not provider.logo: continue # Check if image already exists in library existing_image = ImageLibrary.objects.filter( name=f"{provider.name} Logo" ).first() if existing_image and not force: self.stdout.write( self.style.WARNING( f" - Skipping {provider.name} logo (already exists)" ) ) continue if dry_run: self.stdout.write( self.style.SUCCESS(f" - Would migrate: {provider.name} logo") ) continue # Create image library entry image_lib = ImageLibrary( name=f"{provider.name} Logo", slug=slugify(f"{provider.name}-logo"), description=f"Logo for {provider.name} cloud provider", alt_text=f"{provider.name} logo", category="logo", tags=f"cloud, provider, logo, {provider.name.lower()}", ) # Copy the image file if provider.logo and os.path.exists(provider.logo.path): with open(provider.logo.path, "rb") as f: image_lib.image.save( os.path.basename(provider.logo.name), ContentFile(f.read()), save=True, ) self.stdout.write( self.style.SUCCESS(f" - Migrated: {provider.name} logo") ) else: self.stdout.write( self.style.ERROR( f" - Failed to migrate: {provider.name} logo (file not found)" ) ) def migrate_partner_logos(self, dry_run, force): """ Migrate consulting partner logos to the image library. """ self.stdout.write("Migrating consulting partner logos...") partners = ConsultingPartner.objects.filter(logo__isnull=False).exclude(logo="") for partner in partners: if not partner.logo: continue # Check if image already exists in library existing_image = ImageLibrary.objects.filter( name=f"{partner.name} Logo" ).first() if existing_image and not force: self.stdout.write( self.style.WARNING( f" - Skipping {partner.name} logo (already exists)" ) ) continue if dry_run: self.stdout.write( self.style.SUCCESS(f" - Would migrate: {partner.name} logo") ) continue # Create image library entry image_lib = ImageLibrary( name=f"{partner.name} Logo", slug=slugify(f"{partner.name}-logo"), description=f"Logo for {partner.name} consulting partner", alt_text=f"{partner.name} logo", category="logo", tags=f"consulting, partner, logo, {partner.name.lower()}", ) # Copy the image file if partner.logo and os.path.exists(partner.logo.path): with open(partner.logo.path, "rb") as f: image_lib.image.save( os.path.basename(partner.logo.name), ContentFile(f.read()), save=True, ) self.stdout.write( self.style.SUCCESS(f" - Migrated: {partner.name} logo") ) else: self.stdout.write( self.style.ERROR( f" - Failed to migrate: {partner.name} logo (file not found)" ) ) def migrate_article_images(self, dry_run, force): """ Migrate article images to the image library. """ self.stdout.write("Migrating article images...") articles = Article.objects.filter(image__isnull=False).exclude(image="") for article in articles: if not article.image: continue # Check if image already exists in library existing_image = ImageLibrary.objects.filter( name=f"{article.title} Image" ).first() if existing_image and not force: self.stdout.write( self.style.WARNING( f" - Skipping {article.title} image (already exists)" ) ) continue if dry_run: self.stdout.write( self.style.SUCCESS(f" - Would migrate: {article.title} image") ) continue # Create image library entry image_lib = ImageLibrary( name=f"{article.title} Image", slug=slugify(f"{article.title}-image"), description=f"Feature image for article: {article.title}", alt_text=f"{article.title} feature image", category="article", tags=f"article, {article.title.lower()}", ) # Copy the image file if article.image and os.path.exists(article.image.path): with open(article.image.path, "rb") as f: image_lib.image.save( os.path.basename(article.image.name), ContentFile(f.read()), save=True, ) self.stdout.write( self.style.SUCCESS(f" - Migrated: {article.title} image") ) else: self.stdout.write( self.style.ERROR( f" - Failed to migrate: {article.title} image (file not found)" ) )