photolib/photoapp/thumbtool.py

49 lines
1.8 KiB
Python

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