Fix #1053 - Add height and width attributes and MetadataProcess task
Added "height" and "width" attributes to "image" and "fullImage" in the API where possible. The height and width of images wasn't being stored anywhere so I've created a task to add or update the metadata on images and also started adding those to new images when they're submitted in the InitialProcessor.
This commit is contained in:
parent
f2698759cd
commit
4a09d5956a
@ -591,6 +591,22 @@ class MediaEntry(Base, MediaEntryMixin):
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add image height and width if possible. We didn't use to store this
|
||||||
|
# data and we're not able (and maybe not willing) to re-process all
|
||||||
|
# images so it's possible this might not exist.
|
||||||
|
if self.get_file_metadata("thumb", "height"):
|
||||||
|
height = self.get_file_metadata("thumb", "height")
|
||||||
|
context["image"]["height"] = height
|
||||||
|
if self.get_file_metadata("thumb", "width"):
|
||||||
|
width = self.get_file_metadata("thumb", "width")
|
||||||
|
context["image"]["width"] = width
|
||||||
|
if self.get_file_metadata("original", "height"):
|
||||||
|
height = self.get_file_metadata("original", "height")
|
||||||
|
context["fullImage"]["height"] = height
|
||||||
|
if self.get_file_metadata("original", "height"):
|
||||||
|
width = self.get_file_metadata("original", "width")
|
||||||
|
context["fullImage"]["width"] = width
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def unserialize(self, data):
|
def unserialize(self, data):
|
||||||
|
@ -225,19 +225,32 @@ class CommonImageProcessor(MediaProcessor):
|
|||||||
self.entry, self.process_filename,
|
self.entry, self.process_filename,
|
||||||
self.name_builder.fill('{basename}{ext}'))
|
self.name_builder.fill('{basename}{ext}'))
|
||||||
|
|
||||||
def extract_metadata(self):
|
def extract_metadata(self, file):
|
||||||
# Is there any GPS data
|
""" Extract all the metadata from the image and store """
|
||||||
|
# Extract GPS data and store in Location
|
||||||
gps_data = get_gps_data(self.exif_tags)
|
gps_data = get_gps_data(self.exif_tags)
|
||||||
|
|
||||||
|
if len(gps_data):
|
||||||
|
Location.create({"position": gps_data}, self.entry)
|
||||||
|
|
||||||
# Insert exif data into database
|
# Insert exif data into database
|
||||||
exif_all = clean_exif(self.exif_tags)
|
exif_all = clean_exif(self.exif_tags)
|
||||||
|
|
||||||
if len(exif_all):
|
if len(exif_all):
|
||||||
self.entry.media_data_init(exif_all=exif_all)
|
self.entry.media_data_init(exif_all=exif_all)
|
||||||
|
|
||||||
if len(gps_data):
|
# Extract file metadata
|
||||||
Location.create({"position": gps_data}, self.entry)
|
try:
|
||||||
self.entry.media_data_init(**gps_data)
|
im = Image.open(self.process_filename)
|
||||||
|
except IOError:
|
||||||
|
raise BadMediaFail()
|
||||||
|
|
||||||
|
metadata = {
|
||||||
|
"width": im.size[0],
|
||||||
|
"height": im.size[1],
|
||||||
|
}
|
||||||
|
|
||||||
|
self.entry.set_file_metadata(file, **metadata)
|
||||||
|
|
||||||
|
|
||||||
class InitialProcessor(CommonImageProcessor):
|
class InitialProcessor(CommonImageProcessor):
|
||||||
@ -252,6 +265,9 @@ class InitialProcessor(CommonImageProcessor):
|
|||||||
"""
|
"""
|
||||||
Determine if this media type is eligible for processing
|
Determine if this media type is eligible for processing
|
||||||
"""
|
"""
|
||||||
|
if entry is None and state is None:
|
||||||
|
raise ValueError("Must specify either entry or state")
|
||||||
|
|
||||||
if not state:
|
if not state:
|
||||||
state = entry.state
|
state = entry.state
|
||||||
return state in (
|
return state in (
|
||||||
@ -301,7 +317,7 @@ class InitialProcessor(CommonImageProcessor):
|
|||||||
quality=quality)
|
quality=quality)
|
||||||
self.generate_thumb(size=thumb_size, filter=filter, quality=quality)
|
self.generate_thumb(size=thumb_size, filter=filter, quality=quality)
|
||||||
self.copy_original()
|
self.copy_original()
|
||||||
self.extract_metadata()
|
self.extract_metadata('original')
|
||||||
self.delete_queue_file()
|
self.delete_queue_file()
|
||||||
|
|
||||||
|
|
||||||
@ -318,6 +334,9 @@ class Resizer(CommonImageProcessor):
|
|||||||
"""
|
"""
|
||||||
Determine if this media type is eligible for processing
|
Determine if this media type is eligible for processing
|
||||||
"""
|
"""
|
||||||
|
if entry is None and state is None:
|
||||||
|
raise ValueError("Must specify either entry or state")
|
||||||
|
|
||||||
if not state:
|
if not state:
|
||||||
state = entry.state
|
state = entry.state
|
||||||
return state in 'processed'
|
return state in 'processed'
|
||||||
@ -366,13 +385,52 @@ class Resizer(CommonImageProcessor):
|
|||||||
elif file == 'thumb':
|
elif file == 'thumb':
|
||||||
self.generate_thumb(size=size, filter=filter, quality=quality)
|
self.generate_thumb(size=size, filter=filter, quality=quality)
|
||||||
|
|
||||||
|
self.extract_metadata(file)
|
||||||
|
|
||||||
|
class MetadataProcessing(CommonImageProcessor):
|
||||||
|
""" Extraction and storage of media's metadata for processed images """
|
||||||
|
|
||||||
|
name = 'metadatabuilder'
|
||||||
|
description = 'Add or update image metadata'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def media_is_eligible(cls, entry=None, state=None):
|
||||||
|
if entry is None and state is None:
|
||||||
|
raise ValueError("Must specify either entry or state")
|
||||||
|
|
||||||
|
if state is None:
|
||||||
|
state = entry.state
|
||||||
|
|
||||||
|
return state == 'processed'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate_parser(cls):
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description=cls.description,
|
||||||
|
prog=cls.name
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'file',
|
||||||
|
choices=['original', 'medium', 'thumb']
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def args_to_request(cls, args):
|
||||||
|
return request_from_args(args, ['file'])
|
||||||
|
|
||||||
|
def process(self, file):
|
||||||
|
self.common_setup()
|
||||||
|
self.extract_metadata(file)
|
||||||
|
|
||||||
class ImageProcessingManager(ProcessingManager):
|
class ImageProcessingManager(ProcessingManager):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ImageProcessingManager, self).__init__()
|
super(ImageProcessingManager, self).__init__()
|
||||||
self.add_processor(InitialProcessor)
|
self.add_processor(InitialProcessor)
|
||||||
self.add_processor(Resizer)
|
self.add_processor(Resizer)
|
||||||
|
self.add_processor(MetadataProcessing)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
|
Loading…
x
Reference in New Issue
Block a user