refactor image thumbnail generation code
parent
636a386ec4
commit
44e7bc81d6
@ -0,0 +1,48 @@
|
||||
import os
|
||||
from collections import defaultdict
|
||||
import tempfile
|
||||
from shutil import copyfileobj
|
||||
from contextlib import closing
|
||||
from photoapp.thumb import thumb_path, image_file_style_process
|
||||
|
||||
|
||||
class ThumbGenerator(object):
|
||||
def __init__(self, library, storage):
|
||||
self.library = library
|
||||
self.storage = storage
|
||||
self._failed_thumbs_cache = defaultdict(dict)
|
||||
|
||||
def make_thumb(self, photo, style_name):
|
||||
"""
|
||||
Create a thumbnail of the given photo, scaled/cropped to the given named style
|
||||
:return: local path to thumbnail file or None if creation failed or was blocked
|
||||
"""
|
||||
dest = thumb_path(style_name, photo.uuid)
|
||||
|
||||
if self.storage.exists(dest):
|
||||
return self.storage.open(dest, "rb")
|
||||
|
||||
if photo.uuid in self._failed_thumbs_cache[style_name]:
|
||||
return None
|
||||
|
||||
# if photo.width is None: # todo better detection of images that PIL can't open
|
||||
# return None
|
||||
|
||||
# TODO have the subprocess download the file
|
||||
# TODO thundering herd
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
fthumblocal = tempfile.NamedTemporaryFile(delete=True)
|
||||
fpath = os.path.join(tmpdir, "image")
|
||||
with self.library.storage.open(photo.path, 'rb') as fsrc:
|
||||
with open(fpath, 'wb') as ftmpdest:
|
||||
copyfileobj(fsrc, ftmpdest)
|
||||
|
||||
if not image_file_style_process(fpath, fthumblocal.name, style_name, photo.orientation):
|
||||
self._failed_thumbs_cache[style_name][photo.uuid] = True # dont retry failed generations
|
||||
return
|
||||
|
||||
with closing(self.storage.open(dest, 'wb')) as fdest:
|
||||
copyfileobj(fthumblocal, fdest)
|
||||
|
||||
fthumblocal.seek(0)
|
||||
return fthumblocal
|
Loading…
Reference in New Issue