src/iconolab_episteme/management/commands/importcollection.py
author Riwad Salim
Tue, 26 Jun 2018 15:55:08 +0200
changeset 0 df27f9610c82
permissions -rw-r--r--
Creating iconolab episteme project

# -*- 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 collection image and file from a directory'

    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-json',
            dest='collection_json',
            default=False,
            help='creates a new collection from a json file, must be an object with fields : '+ 
                 '"name" (identifier), '+ 
                 '"verbose_name" (proper title name), '+ 
                 '"description" (description on homepage, html is supported), '+ 
                 '"image" (image on homepages, must be "uploads/<imgname>"), '+ 
                 '"height" and "width" (height and width of the image)',
        )
        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):
            
        print('# Logging with logger '+logger.name)
        logger.debug('# Initializing command with args: %r', options)

        '''Check we have a collection to store data into'''
        self.source_dir = options.get('source_dir')
        print('# Checking collection args')
        if options.get('collection_json'):
            print('## Finding collection json data in '+self.source_dir)
            collection_json_path = os.path.join(
                self.source_dir, options.get('collection_json'))
            if not os.path.isfile(collection_json_path):
                print('### No '+options.get('collection_json') +
                        '.json file was found in the source directory')
                raise ValueError(
                    '!!! Json file '+collection_json_path+' was not found !!!')
            try:
                with open(collection_json_path) as json_fixture_file:
                    collection_data = json.loads(json_fixture_file.read())
                    for key in ['name', 'verbose_name', 'description', 'image', 'height', 'width']:
                        if not key in collection_data.keys():
                            print('!!! Json file '+collection_json_path +
                                    ' has no '+key+' field !!!')
                            raise ValueError()
                    if not collection_data.get('name', ''):
                        print('!!! Collection data key "name" is empty')
                        raise ValueError()
                    if Collection.objects.filter(name=collection_data.get('name')).exists():
                        print(
                            '!!! A Collection with the provided name already exists!')
                        raise ValueError()
                    if collection_data.get('image', '') and not (collection_data.get('width', 0) and collection_data.get('height', 0)):
                        print(
                            '!!! Collection data has an image but no height and width')
                        raise ValueError()
            except ValueError as e:
                raise ValueError('!!! JSON Data is invalid. !!!')
        elif 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. !!!')


        '''Import image collection in target directory'''
           
        if options.get('collection_json'):
            print('## Loading collection json')
            collection = Collection.objects.create(
                name=collection_data.get('name'),
                verbose_name=collection_data.get('verbose_name', ''),
                description=collection_data.get('description', ''),
                image=collection_data.get('image', ''),
                height=collection_data.get('height', 0),
                width=collection_data.get('width', 0),
            )

            if collection.image:
                collection_image_path = os.path.join(
                    settings.MEDIA_ROOT, str(collection.image))
                if not os.path.isfile(collection_image_path):
                    print('### Moving collection image')
                    _, collection_image_name = os.path.split(
                        collection_image_path)
                    try:
                        col_im = ImagePIL.open(os.path.join(
                            self.source_dir, collection_image_name))
                        print('##### Generating or copying jpeg for ' +
                                collection_image_name)
                        col_im.thumbnail(col_im.size)
                        col_im.save(collection_image_path, 'JPEG', quality=options.get(
                            'jpeg_quality', settings.IMG_JPG_DEFAULT_QUALITY))
                    except Exception as e:
                        print(e)