# coding=utf-8 from django.core.management.base import BaseCommand from utils.methods import get_url_images_in_text, get_image_meta_by_url from news.models import News from sorl.thumbnail import get_thumbnail class Command(BaseCommand): IMAGE_MAX_SIZE_IN_BYTES = 1048576 # ~ 1mb IMAGE_QUALITY_PERCENTS = 50 def add_arguments(self, parser): parser.add_argument( '-s', '--size', default=self.IMAGE_MAX_SIZE_IN_BYTES, help='Максимальный размер файла в байтах', type=int ) parser.add_argument( '-q', '--quality', default=self.IMAGE_QUALITY_PERCENTS, help='Качество изображения', type=int ) def optimize(self, text, max_size, max_quality): """optimize news images""" if isinstance(text, str): for image in get_url_images_in_text(text): try: size, width, height = get_image_meta_by_url(image) except IOError as ie: self.stdout.write(self.style.NOTICE(f'{ie}\n')) continue if size < max_size: self.stdout.write(self.style.SUCCESS(f'No need to compress images size is {size / (2**20)}Mb\n')) continue percents = round(max_size / (size * 0.01)) width = round(width * percents / 100) height = round(height * percents / 100) optimized_image = get_thumbnail( file_=image, geometry_string=f'{width}x{height}', upscale=False, quality=max_quality ).url text = text.replace(image, optimized_image) self.stdout.write(self.style.SUCCESS(f'Optimized {image} -> {optimized_image}\n' f'Quality [{percents}%]\n')) return text def handle(self, *args, **options): size = options['size'] quality = options['quality'] for news in News.objects.all(): if not isinstance(news.description, dict): continue news.description = { locale: self.optimize(text, size, quality) for locale, text in news.description.items() } news.save()