src/iconolab/management/commands/importimages.py
author ymh <ymh.work@gmail.com>
Wed, 01 Aug 2018 19:05:27 +0200
changeset 582 9ae978afd7b3
parent 580 ae6aea2321f8
child 584 b5f3daa86400
permissions -rw-r--r--
Generate a valid image dir name
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
import json
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
     2
import math
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
import os
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
import shutil
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
from django.conf import settings
546
59d7cb99f4df small import image correction. Check the target dir
ymh <ymh.work@gmail.com>
parents: 544
diff changeset
     7
from django.core.management.base import BaseCommand, CommandError
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
     8
from django.db import transaction
582
9ae978afd7b3 Generate a valid image dir name
ymh <ymh.work@gmail.com>
parents: 580
diff changeset
     9
from django.utils import text
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
from PIL import Image as ImagePIL
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
from sorl.thumbnail import get_thumbnail
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
from iconolab.models import Image, ImageStats, Item, ItemMetadata
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
class BaseImportImagesCommand(BaseCommand):
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
    def handle(self, *args, **options):
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
        raise NotImplementedError
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    21
    def get_image_dir(self, natural_key, collection):
582
9ae978afd7b3 Generate a valid image dir name
ymh <ymh.work@gmail.com>
parents: 580
diff changeset
    22
        return os.path.join(
9ae978afd7b3 Generate a valid image dir name
ymh <ymh.work@gmail.com>
parents: 580
diff changeset
    23
            collection.name,
9ae978afd7b3 Generate a valid image dir name
ymh <ymh.work@gmail.com>
parents: 580
diff changeset
    24
            text.get_valid_filename(natural_key.replace('|', '__'))
9ae978afd7b3 Generate a valid image dir name
ymh <ymh.work@gmail.com>
parents: 580
diff changeset
    25
        )
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    26
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    27
    ##
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
    def create_item_and_metadata(
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
            self,
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
            natural_key,
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
            collection,
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
            metadata_dict,
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
            image_files,
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    34
            options
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    ):
546
59d7cb99f4df small import image correction. Check the target dir
ymh <ymh.work@gmail.com>
parents: 544
diff changeset
    36
59d7cb99f4df small import image correction. Check the target dir
ymh <ymh.work@gmail.com>
parents: 544
diff changeset
    37
        target_dir = os.path.join(settings.MEDIA_ROOT, Image.media.field.upload_to)
59d7cb99f4df small import image correction. Check the target dir
ymh <ymh.work@gmail.com>
parents: 544
diff changeset
    38
        if not os.path.isdir(target_dir):
59d7cb99f4df small import image correction. Check the target dir
ymh <ymh.work@gmail.com>
parents: 544
diff changeset
    39
            raise CommandError("Image target dir does not exists : %s" % target_dir)
59d7cb99f4df small import image correction. Check the target dir
ymh <ymh.work@gmail.com>
parents: 544
diff changeset
    40
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    41
        # TODO: Make it fully transactional. if there is a problem on the image creation, some data
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    42
        # files can persists.
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    43
        with transaction.atomic():
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    44
            print('#### Creating item '+natural_key+' (natural key) in database')
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    45
            item_object = Item.objects.create(
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    46
                collection=collection
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    47
            )
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    49
            ItemMetadata.objects.create(
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    50
                item=item_object,
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    51
                metadata=json.dumps(metadata_dict),
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    52
                natural_key=natural_key
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    53
            )
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    55
            print('#### preparing image folder for item ' + natural_key)
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    56
            item_image_dir = self.get_image_dir(natural_key, collection)
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    57
            target_item_image_dir = os.path.join(target_dir, item_image_dir)
578
4285827101e3 Change error in method name
ymh <ymh.work@gmail.com>
parents: 576
diff changeset
    58
            os.makedirs(target_item_image_dir, exist_ok=True)
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    59
            print('-->' + target_item_image_dir, "directory created")
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    60
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    61
            print('#### Computing item image(s)')
580
ae6aea2321f8 Convert log to int.
ymh <ymh.work@gmail.com>
parents: 578
diff changeset
    62
            image_file_name_fill = int(math.log10(len(image_files)))+1
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    63
            for i, image in enumerate(image_files):
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    64
                (_, ext) = os.path.splitext(image)
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    65
                dest_image_name = "{0}_{1:0{2}d}.jpg".format(natural_key, i+1, image_file_name_fill)
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    66
                image_path = os.path.join(target_item_image_dir, dest_image_name)
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    67
                if options.get('no-jpg-conversion') or ext in settings.NO_IMG_CONVERSION_EXTS:
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    68
                    print('##### Copying file %s to %s without converting'%(str(image), image_path))
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    69
                    shutil.copy(image, image_path)
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
                else:
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    71
                    if os.path.isfile(image_path):
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    72
                        print('##### A jpeg file already exists in target dir for %s' % image)
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    73
                    else:
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    74
                        im = ImagePIL.open(image)
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    75
                        print('##### Generating or copying jpeg for %s to %s' % (image, image_path))
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
                        im.thumbnail(im.size)
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    77
                        im.save(image_path, 'JPEG', quality=options.get(
544
3e48e2e2c0ce Create a generic import image command
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
                            'jpeg_quality', settings.IMG_JPG_DEFAULT_QUALITY))
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    79
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    80
                new_image = Image.objects.create(
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    81
                    item=item_object,
576
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    82
                    media=os.path.join(Image.media.field.upload_to, item_image_dir, dest_image_name),
68ea0b063308 Change the way images are handled and stored in importimages.
ymh <ymh.work@gmail.com>
parents: 557
diff changeset
    83
                    name=os.path.join(item_image_dir, dest_image_name)
557
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    84
                )
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    85
                ImageStats.objects.create(
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    86
                    image=new_image
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    87
                )
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    88
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    89
            print('### Generating thumbnails for item '+natural_key)
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    90
            for image in item_object.images.all():
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    91
                for size in settings.PREGENERATE_THUMBNAILS_SIZES:
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    92
                    print('#### Thumbnail for size '+size)
7301141078de better error management in importimages
ymh <ymh.work@gmail.com>
parents: 555
diff changeset
    93
                    get_thumbnail(image.media, size, crop=False)