#!/usr/bin/env python3 # -*- encoding: utf-8 -*- import json from pathlib import Path import PIL import PIL.Image import PIL.ImageOps import subprocess import filetype import hashlib import uuid def main(): pass def thumbnailize(target_file: Path): thumbs_dict = dict() target = target_file.parent target_hashfile = target.joinpath(target_file.name+'.sha256') target_meta = target.joinpath('_meta.json') meta = json.loads(target_meta.read_text()) ext = meta['ext'] thumb_sizes = [4, 8, 16, 24, 32, 48, 64, 72, 96, 128] thumbs_dir = target.joinpath('thumbs') thumbs_dir.mkdir(parents=True, exist_ok=True) thumbs_dict['sizes'] = thumb_sizes thumbs_dict['full'] = target_hashfile.read_text() thumbs_dict['thumbs'] = None for size in thumb_sizes: thumb_file = thumbs_dir.joinpath(f"thumb_{size}.png",) thumb_hashfile = thumbs_dir.joinpath(f"thumb_{size}.png.md5",) if not thumb_file.exists(): gen_thumb(ext, target_file, thumb_file, size) if thumb_file.exists(): if thumbs_dict['thumbs'] is None: thumbs_dict['thumbs'] = dict() thumbs_dict['thumbs'][f'{size}'] = dict() if not thumb_hashfile.exists(): m = hashlib.md5() m.update(thumb_file.read_bytes()) thumb_hashfile.write_text(m.hexdigest()) thumbs_dict['thumbs'][f'{size}']['rectangular'] = thumb_hashfile.read_text() thumbs_dict['thumb'] = thumb_hashfile.read_text() for size in thumb_sizes: thumb_file = thumbs_dir.joinpath(f"thumb_{size}.png",) if thumb_file.exists(): thumb_square_file = thumbs_dir.joinpath(f"thumb_square_{size}.png",) thumb_square_hashfile = thumbs_dir.joinpath(f"thumb_square_{size}.png.md5",) image = None if not thumb_square_file.exists(): square = PIL.Image.new('RGB', (size, size), (0, 0, 0)) image = PIL.Image.open(thumb_file) img_w, img_h = image.size offset = ((size - img_w) // 2, (size - img_h) // 2) square.paste(image, offset) del img_h del img_w del image del offset square.save(thumb_square_file, 'png') image = square del square if not thumb_square_hashfile.exists(): m = hashlib.md5() m.update(thumb_square_file.read_bytes()) thumb_square_hashfile.write_text(m.hexdigest()) thumbs_dict['thumbs'][f'{size}']['square'] = dict() thumbs_dict['thumbs'][f'{size}']['square']['original'] = thumb_square_hashfile.read_text() thumbs_dict['thumbs'][f'{size}']['square']['posterized'] = dict() for pl in range(1,9): thumb_square_file_posterized = thumbs_dir.joinpath(f"thumb_square_{size}_posterized_{pl}.png",) thumb_square_hashfile_posterized = thumbs_dir.joinpath(f"thumb_square_{size}_posterized_{pl}.png.md5",) if not thumb_square_file_posterized.exists(): if image is None: image = PIL.Image.open(thumb_square_file) posterized = PIL.ImageOps.posterize(image, pl) posterized.save(thumb_square_file_posterized, 'png') del posterized if not thumb_square_hashfile_posterized.exists(): m = hashlib.md5() m.update(thumb_square_file_posterized.read_bytes()) thumb_square_hashfile_posterized.write_text(m.hexdigest()) thumbs_dict['thumbs'][f'{size}']['square']['posterized'][f'{pl}'] = thumb_square_hashfile_posterized.read_text() del image return thumbs_dict def gen_thumb(ext, target_file, thumb_file, size): if ext!='unk': actualext = 'unk' with target_file.open('rb') as f: actualext = filetype.guess_extension(f) actualext = actualext if actualext else 'unk' if actualext!='unk': r = subprocess.run( ['ffmpegthumbnailer', '-i', str(target_file), '-o', '-', '-c', 'png', '-q', '10', '-s', str(size)], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) if r.returncode and actualext in ('jpg', 'png', 'gif'): tmpfile = Path('/tmp').joinpath(f'{uuid.uuid4().hex}.png') r = subprocess.run( ['gdk-pixbuf-thumbnailer', '-s', str(size), str(target_file), str(tmpfile)], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) r.check_returncode() r = subprocess.run( ['cat', str(tmpfile)], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) tmpfile.unlink() else: r.check_returncode() thumb_file.write_bytes(r.stdout) if __name__ == "__main__": main()