This commit is contained in:
Erik Johnston 2017-10-13 11:33:49 +01:00
parent 505371414f
commit 0e28281a02
2 changed files with 32 additions and 43 deletions

View File

@ -131,10 +131,9 @@ class MediaRepository(object):
fname = os.path.join(self.primary_base_path, path) fname = os.path.join(self.primary_base_path, path)
# Write to the main repository # Write to the main repository
yield make_deferred_yieldable( yield make_deferred_yieldable(threads.deferToThread(
threads.deferToThread,
self._write_file_synchronously, source, fname, self._write_file_synchronously, source, fname,
) ))
# Write to backup repository # Write to backup repository
yield self.copy_to_backup(source, path) yield self.copy_to_backup(source, path)
@ -157,11 +156,10 @@ class MediaRepository(object):
# We can either wait for successful writing to the backup repository # We can either wait for successful writing to the backup repository
# or write in the background and immediately return # or write in the background and immediately return
if self.synchronous_backup_media_store: if self.synchronous_backup_media_store:
yield make_deferred_yieldable( yield make_deferred_yieldable(threads.deferToThread(
threads.deferToThread,
self._write_file_synchronously, source, backup_fname, self._write_file_synchronously, source, backup_fname,
close_source=True, close_source=True,
) ))
else: else:
preserve_fn(threads.deferToThread)( preserve_fn(threads.deferToThread)(
self._write_file_synchronously, source, backup_fname, self._write_file_synchronously, source, backup_fname,
@ -378,11 +376,10 @@ class MediaRepository(object):
input_path = self.filepaths.local_media_filepath(media_id) input_path = self.filepaths.local_media_filepath(media_id)
thumbnailer = Thumbnailer(input_path) thumbnailer = Thumbnailer(input_path)
t_byte_source = yield make_deferred_yieldable( t_byte_source = yield make_deferred_yieldable(threads.deferToThread(
threads.deferToThread,
self._generate_thumbnail, self._generate_thumbnail,
thumbnailer, t_width, t_height, t_method, t_type thumbnailer, t_width, t_height, t_method, t_type
) ))
if t_byte_source: if t_byte_source:
t_width, t_height = t_byte_source.dimensions t_width, t_height = t_byte_source.dimensions
@ -409,11 +406,10 @@ class MediaRepository(object):
input_path = self.filepaths.remote_media_filepath(server_name, file_id) input_path = self.filepaths.remote_media_filepath(server_name, file_id)
thumbnailer = Thumbnailer(input_path) thumbnailer = Thumbnailer(input_path)
t_byte_source = yield make_deferred_yieldable( t_byte_source = yield make_deferred_yieldable(threads.deferToThread(
threads.deferToThread,
self._generate_thumbnail, self._generate_thumbnail,
thumbnailer, t_width, t_height, t_method, t_type thumbnailer, t_width, t_height, t_method, t_type
) ))
if t_byte_source: if t_byte_source:
t_width, t_height = t_byte_source.dimensions t_width, t_height = t_byte_source.dimensions
@ -478,34 +474,32 @@ class MediaRepository(object):
thumbnails = {} thumbnails = {}
for r_width, r_height, r_method, r_type in requirements: for r_width, r_height, r_method, r_type in requirements:
if r_method == "crop": if r_method == "crop":
thumbnails.setdefault[(r_width, r_height)] = (r_method, r_type) thumbnails.setdefault((r_width, r_height), (r_method, r_type))
elif r_method == "scale": elif r_method == "scale":
t_width, t_height = thumbnailer.aspect(t_width, t_height) t_width, t_height = thumbnailer.aspect(r_width, r_height)
t_width = min(m_width, t_width) t_width = min(m_width, t_width)
t_height = min(m_height, t_height) t_height = min(m_height, t_height)
thumbnails[(t_width, t_height)] = (r_method, r_type) thumbnails[(t_width, t_height)] = (r_method, r_type)
# Now we generate the thumbnails for each dimension, store it # Now we generate the thumbnails for each dimension, store it
for (r_width, r_height), (r_method, r_type) in thumbnails.iteritems(): for (t_width, t_height), (t_method, t_type) in thumbnails.iteritems():
t_byte_source = thumbnailer.crop(t_width, t_height, t_type) # Generate the thumbnail
if t_type == "crop":
if r_type == "crop": t_byte_source = yield make_deferred_yieldable(threads.deferToThread(
t_byte_source = yield make_deferred_yieldable( thumbnailer.crop,
threads.deferToThread, thumbnailer.crop, r_width, r_height, t_type,
r_width, r_height, r_type, ))
)
else: else:
t_byte_source = yield make_deferred_yieldable( t_byte_source = yield make_deferred_yieldable(threads.deferToThread(
threads.deferToThread, thumbnailer.scale, thumbnailer.scale,
r_width, r_height, r_type, r_width, r_height, t_type,
) ))
t_width, t_height = t_byte_source.dimensions
# Work out the correct file name for thumbnail
if server_name: if server_name:
file_path = self.filepaths.remote_media_thumbnail_rel( file_path = self.filepaths.remote_media_thumbnail_rel(
server_name, file_id, t_width, t_height, t_type, t_method server_name, file_id, t_width, t_height, t_type, t_method
) )
elif url_cache: elif url_cache:
file_path = self.filepaths.url_cache_thumbnail_rel( file_path = self.filepaths.url_cache_thumbnail_rel(
media_id, t_width, t_height, t_type, t_method media_id, t_width, t_height, t_type, t_method
@ -515,14 +509,16 @@ class MediaRepository(object):
media_id, t_width, t_height, t_type, t_method media_id, t_width, t_height, t_type, t_method
) )
# Write to disk
output_path = yield self.write_to_file(t_byte_source, file_path) output_path = yield self.write_to_file(t_byte_source, file_path)
t_len = os.path.getsize(output_path) t_len = os.path.getsize(output_path)
# Write to database
if server_name: if server_name:
yield self.store.store_remote_media_thumbnail( yield self.store.store_remote_media_thumbnail(
server_name, media_id, file_id, server_name, media_id, file_id,
t_width, t_height, t_type, t_method, t_len t_width, t_height, t_type, t_method, t_len
) )
else: else:
yield self.store.store_local_thumbnail( yield self.store.store_local_thumbnail(
media_id, t_width, t_height, t_type, t_method, t_len media_id, t_width, t_height, t_type, t_method, t_len

View File

@ -54,7 +54,7 @@ class Thumbnailer(object):
"""Rescales the image to the given dimensions. """Rescales the image to the given dimensions.
Returns: Returns:
ImageIO: the bytes of the encoded image ready to be written to disk BytesIO: the bytes of the encoded image ready to be written to disk
""" """
scaled = self.image.resize((width, height), Image.ANTIALIAS) scaled = self.image.resize((width, height), Image.ANTIALIAS)
return self._encode_image(scaled, output_type) return self._encode_image(scaled, output_type)
@ -71,7 +71,7 @@ class Thumbnailer(object):
max_height: The larget possible height. max_height: The larget possible height.
Returns: Returns:
ImageIO: the bytes of the encoded image ready to be written to disk BytesIO: the bytes of the encoded image ready to be written to disk
""" """
if width * self.height > height * self.width: if width * self.height > height * self.width:
scaled_height = (width * self.height) // self.width scaled_height = (width * self.height) // self.width
@ -92,13 +92,6 @@ class Thumbnailer(object):
return self._encode_image(cropped, output_type) return self._encode_image(cropped, output_type)
def _encode_image(self, output_image, output_type): def _encode_image(self, output_image, output_type):
output_bytes_io = ImageIO(output_image.size) output_bytes_io = BytesIO()
output_image.save(output_bytes_io, self.FORMATS[output_type], quality=80) output_image.save(output_bytes_io, self.FORMATS[output_type], quality=80)
output_image.close()
return output_bytes_io return output_bytes_io
class ImageIO(BytesIO):
def __init__(self, dimensions):
super(ImageIO, self).__init__()
self.dimensions = dimensions