src/iconolab_episteme/management/commands/importimages.py
author ymh <ymh.work@gmail.com>
Wed, 27 Jun 2018 16:00:29 +0200
changeset 1 3b0a8a6e685e
parent 0 df27f9610c82
child 3 16fb4f5efa69
permissions -rw-r--r--
* Move importcollection and importmetacategories commands to the generic project * Add site synchronisation script * Add some test data * remove dev settings * Add setup file to build the application * update .hgignore

# -*- 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(
            '--encoding',
            dest='encoding',
            default='utf-8',
            help='JSON file encoding'

        )
        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'
        )
        parser.add_argument(
            '--folders',
            dest='import_folders',
            default=False,
            action='store_const',
            const=True,
            help='option to create folders'
        )
        # parser.add_argument(
        #     '--folders-regexp',
        #     dest='folders_regexp',
        #     default=False,
        #     help='regexp used to extract the folder name/number'
        # )
        # parser.add_argument(
        #     '--folders-metadata',
        #     dest='folders_metadata',
        #     default='REF',
        #     help='metadata from which to extract the folder name/number'
        # )

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

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

        if options.get('collection_id'):
            print('## Finding collection with id ' + 
                    options.get('collection_id'))
            try:
                collection = Collection.objects.get(
                    pk=options.get('collection_id'))
            except Collection.DoesNotExist:
                raise ValueError('!!! Collection with primary key ' +
                                    options.get('collection_id')+' was not found, aborting !!!')
        else:
            raise ValueError(
                '!!! No collection fixture or collection id, aborting because we can\'t properly generate data. !!!')


        '''Listing image files in target directory'''

        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:
                filename_without_extension, extension = os.path.splitext(filename)
                if imghdr.what(os.path.join(dirname, filename)) is None:
                    continue

                json_path = os.path.join(dirname, filename_without_extension + ".json")
                if not os.path.isfile(json_path):
                    continue

                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")

                        self.create_item_and_metadata(
                            natural_key, collection, eso_data, image_list, options, self.source_dir)

        print('# All done!')