src/iconolab_episteme/management/commands/importimages.py
author ymh <ymh.work@gmail.com>
Thu, 28 Jun 2018 18:50:20 +0200
changeset 7 a40fd3990850
parent 3 16fb4f5efa69
permissions -rw-r--r--
skip already processed images

# -*- coding: UTF-8 -*-
import json
import logging
import os
import pprint
import re
import shutil
import imghdr

from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from PIL import Image as ImagePIL
from sorl.thumbnail import get_thumbnail

from iconolab.management.commands.importimages import BaseImportImagesCommand
from iconolab.models import (Collection, Folder, Image, ImageStats, Item,
                             ItemMetadata, MetaCategory)

if settings.IMPORT_LOGGER_NAME and settings.LOGGING['loggers'].get(settings.IMPORT_LOGGER_NAME, ''):
    logger = logging.getLogger(settings.IMPORT_LOGGER_NAME)
else:
    logger = logging.getLogger(__name__)

class Command(BaseImportImagesCommand):
    help = 'import images from a directory into the media folder and creates item and image objects'

    def add_arguments(self, parser):
        parser.add_argument('source_dir')
        parser.add_argument(
            '--collection-id',
            dest='collection_id',
            default=False,
            help='insert extracted data into the specified collection instead of trying to load a collection fixture',
        )
        parser.add_argument(
            '--no-jpg-conversion',
            dest='no-jpg-conversion',
            default=False,
            help='use this option if you only want the image copied and not converted'
        )

    def handle(self, *args, **options):

        #Set no image size limit to PIL to be able to process big images.
        ImagePIL.MAX_IMAGE_PIXELS = None

        print('# Logging with logger '+logger.name)
        logger.debug('# Initializing command with args: %r', options)
      
        self.source_dir = options.get('source_dir')

        collection_id = options.get('collection_id')

        if not collection_id:
            raise CommandError("No collection id, aborting")

        print('## Finding collection with id %s' % collection_id) 

        try:
            try:
                collection = Collection.objects.get(pk=int(collection_id))
            except ValueError:
                collection = Collection.objects.get(name=collection_id)
        except Collection.DoesNotExist:
            raise CommandError('!!! Collection with id ' + collection_id
                                +' was not found, aborting !!!')

        print(
            '## Converting image and moving it to static dir, creating Image and Item objects')
        print('### Images will be stored in ' + os.path.join(settings.MEDIA_ROOT,'uploads'))

        for dirname, dirs, files in os.walk(self.source_dir):
            for filename in files:
                print("::Examining %s" % filename)
                filename_without_extension, extension = os.path.splitext(filename)
                if imghdr.what(os.path.join(dirname, filename)) is None:
                    print("-> This is not an image: continue")
                    continue

                json_path = os.path.join(dirname, filename_without_extension + ".json")
                if not os.path.isfile(json_path):
                    print("-> has not a matching json: continue")
                    continue

                print("-> Processing %s" %json_path)
                with open(json_path) as json_data:
                    eso_data = json.load(json_data)
                    eso_object = eso_data['object']
                    eso_image = eso_data['image']
                
                    path_images = os.path.join(filename_without_extension, filename)
                    image_list = [path_images]
                    image_dir = filename_without_extension

                    natural_key = ItemMetadata.get_natural_key(collection, eso_image['id'])

                    if ItemMetadata.objects.filter(item__collection=collection, natural_key=natural_key).exists():
                        print('#### An item with ' +
                            natural_key +' for natural key, already exists in database in the import collection')
                    else:
                        try:
                            os.mkdir(os.path.join(settings.MEDIA_ROOT,'uploads', image_dir))
                            print(image_dir, "directory created")
                        except FileExistsError:
                            print(image_dir, "directory already exists")

                        try:
                            self.create_item_and_metadata(
                                natural_key, collection, eso_data, image_list, options, self.source_dir)
                        except Exception as e:
                            print("!!! Exception processing %s : %s" % (json_path, e))
                            continue

        print('# All done!')