1 # -*- coding: UTF-8 -*- |
|
2 import json |
|
3 import logging |
|
4 import os |
|
5 import pprint |
|
6 import re |
|
7 import shutil |
|
8 import imghdr |
|
9 |
|
10 from django.conf import settings |
|
11 from django.core.management.base import BaseCommand, CommandError |
|
12 from PIL import Image as ImagePIL |
|
13 from sorl.thumbnail import get_thumbnail |
|
14 |
|
15 from iconolab.management.commands.importimages import BaseImportImagesCommand |
|
16 from iconolab.models import (Collection, Folder, Image, ImageStats, Item, |
|
17 ItemMetadata, MetaCategory) |
|
18 |
|
19 if settings.IMPORT_LOGGER_NAME and settings.LOGGING['loggers'].get(settings.IMPORT_LOGGER_NAME, ''): |
|
20 logger = logging.getLogger(settings.IMPORT_LOGGER_NAME) |
|
21 else: |
|
22 logger = logging.getLogger(__name__) |
|
23 |
|
24 class Command(BaseImportImagesCommand): |
|
25 help = 'import collection image and file from a directory' |
|
26 |
|
27 def add_arguments(self, parser): |
|
28 parser.add_argument('source_dir') |
|
29 parser.add_argument( |
|
30 '--encoding', |
|
31 dest='encoding', |
|
32 default='utf-8', |
|
33 help='JSON file encoding' |
|
34 |
|
35 ) |
|
36 parser.add_argument( |
|
37 '--collection-json', |
|
38 dest='collection_json', |
|
39 default=False, |
|
40 help='creates a new collection from a json file, must be an object with fields : '+ |
|
41 '"name" (identifier), '+ |
|
42 '"verbose_name" (proper title name), '+ |
|
43 '"description" (description on homepage, html is supported), '+ |
|
44 '"image" (image on homepages, must be "uploads/<imgname>"), '+ |
|
45 '"height" and "width" (height and width of the image)', |
|
46 ) |
|
47 parser.add_argument( |
|
48 '--collection-id', |
|
49 dest='collection_id', |
|
50 default=False, |
|
51 help='insert extracted data into the specified collection instead of trying to load a collection fixture', |
|
52 ) |
|
53 parser.add_argument( |
|
54 '--no-jpg-conversion', |
|
55 dest='no-jpg-conversion', |
|
56 default=False, |
|
57 help='use this option if you only want the image copied and not converted' |
|
58 ) |
|
59 |
|
60 def handle(self, *args, **options): |
|
61 |
|
62 print('# Logging with logger '+logger.name) |
|
63 logger.debug('# Initializing command with args: %r', options) |
|
64 |
|
65 '''Check we have a collection to store data into''' |
|
66 self.source_dir = options.get('source_dir') |
|
67 print('# Checking collection args') |
|
68 if options.get('collection_json'): |
|
69 print('## Finding collection json data in '+self.source_dir) |
|
70 collection_json_path = os.path.join( |
|
71 self.source_dir, options.get('collection_json')) |
|
72 if not os.path.isfile(collection_json_path): |
|
73 print('### No '+options.get('collection_json') + |
|
74 '.json file was found in the source directory') |
|
75 raise ValueError( |
|
76 '!!! Json file '+collection_json_path+' was not found !!!') |
|
77 try: |
|
78 with open(collection_json_path) as json_fixture_file: |
|
79 collection_data = json.loads(json_fixture_file.read()) |
|
80 for key in ['name', 'verbose_name', 'description', 'image', 'height', 'width']: |
|
81 if not key in collection_data.keys(): |
|
82 print('!!! Json file '+collection_json_path + |
|
83 ' has no '+key+' field !!!') |
|
84 raise ValueError() |
|
85 if not collection_data.get('name', ''): |
|
86 print('!!! Collection data key "name" is empty') |
|
87 raise ValueError() |
|
88 if Collection.objects.filter(name=collection_data.get('name')).exists(): |
|
89 print( |
|
90 '!!! A Collection with the provided name already exists!') |
|
91 raise ValueError() |
|
92 if collection_data.get('image', '') and not (collection_data.get('width', 0) and collection_data.get('height', 0)): |
|
93 print( |
|
94 '!!! Collection data has an image but no height and width') |
|
95 raise ValueError() |
|
96 except ValueError as e: |
|
97 raise ValueError('!!! JSON Data is invalid. !!!') |
|
98 elif options.get('collection_id'): |
|
99 print('## Finding collection with id ' + |
|
100 options.get('collection_id')) |
|
101 try: |
|
102 collection = Collection.objects.get( |
|
103 pk=options.get('collection_id')) |
|
104 except Collection.DoesNotExist: |
|
105 raise ValueError('!!! Collection with primary key ' + |
|
106 options.get('collection_id')+' was not found, aborting !!!') |
|
107 else: |
|
108 raise ValueError( |
|
109 '!!! No collection fixture or collection id, aborting because we can\'t properly generate data. !!!') |
|
110 |
|
111 |
|
112 '''Import image collection in target directory''' |
|
113 |
|
114 if options.get('collection_json'): |
|
115 print('## Loading collection json') |
|
116 collection = Collection.objects.create( |
|
117 name=collection_data.get('name'), |
|
118 verbose_name=collection_data.get('verbose_name', ''), |
|
119 description=collection_data.get('description', ''), |
|
120 image=collection_data.get('image', ''), |
|
121 height=collection_data.get('height', 0), |
|
122 width=collection_data.get('width', 0), |
|
123 ) |
|
124 |
|
125 if collection.image: |
|
126 collection_image_path = os.path.join( |
|
127 settings.MEDIA_ROOT, str(collection.image)) |
|
128 if not os.path.isfile(collection_image_path): |
|
129 print('### Moving collection image') |
|
130 _, collection_image_name = os.path.split( |
|
131 collection_image_path) |
|
132 try: |
|
133 col_im = ImagePIL.open(os.path.join( |
|
134 self.source_dir, collection_image_name)) |
|
135 print('##### Generating or copying jpeg for ' + |
|
136 collection_image_name) |
|
137 col_im.thumbnail(col_im.size) |
|
138 col_im.save(collection_image_path, 'JPEG', quality=options.get( |
|
139 'jpeg_quality', settings.IMG_JPG_DEFAULT_QUALITY)) |
|
140 except Exception as e: |
|
141 print(e) |
|
142 |
|
143 |
|