From c88dfd228ac6feedd44fd82330b9899db863a190 Mon Sep 17 00:00:00 2001 From: rr- Date: Fri, 20 May 2016 21:34:02 +0200 Subject: [PATCH] server/images: replace pipes with temp files ffmpeg's GIF demuxer needs the input stream to be seekable, which rules pipes out. --- server/szurubooru/func/images.py | 32 +++++++++++++++++++------------- server/szurubooru/func/util.py | 13 +++++++++++++ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/server/szurubooru/func/images.py b/server/szurubooru/func/images.py index 741d7269..2ac079e2 100644 --- a/server/szurubooru/func/images.py +++ b/server/szurubooru/func/images.py @@ -1,6 +1,7 @@ import json import subprocess from szurubooru import errors +from szurubooru.func import util _SCALE_FIT_FMT = \ r'scale=iw*max({width}/iw\,{height}/ih):ih*max({width}/iw\,{height}/ih)' @@ -24,7 +25,7 @@ class Image(object): def resize_fill(self, width, height): self.content = self._execute([ - '-i', '-', + '-i', '{path}', '-f', 'image2', '-vf', _SCALE_FIT_FMT.format(width=width, height=height), '-vframes', '1', @@ -35,7 +36,7 @@ class Image(object): def to_png(self): return self._execute([ - '-i', '-', + '-i', '{path}', '-f', 'image2', '-vframes', '1', '-vcodec', 'png', @@ -44,7 +45,7 @@ class Image(object): def to_jpeg(self): return self._execute([ - '-i', '-', + '-i', '{path}', '-f', 'image2', '-vframes', '1', '-vcodec', 'mjpeg', @@ -52,16 +53,21 @@ class Image(object): ]) def _execute(self, cli, program='ffmpeg'): - proc = subprocess.Popen( - [program, '-loglevel', '24'] + cli, - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.PIPE) - out, err = proc.communicate(input=self.content) - if proc.returncode != 0: - raise errors.ProcessingError( - 'Error while processing image.\n' + err.decode('utf-8')) - return out + with util.create_temp_file() as handle: + handle.write(self.content) + handle.flush() + cli = [program, '-loglevel', '24'] + cli + cli = [part.format(path=handle.name) for part in cli] + proc = subprocess.Popen( + cli, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = proc.communicate(input=self.content) + if proc.returncode != 0: + raise errors.ProcessingError( + 'Error while processing image.\n' + err.decode('utf-8')) + return out def _reload_info(self): self.info = json.loads(self._execute([ diff --git a/server/szurubooru/func/util.py b/server/szurubooru/func/util.py index f19e7fcc..cdb9f811 100644 --- a/server/szurubooru/func/util.py +++ b/server/szurubooru/func/util.py @@ -1,8 +1,21 @@ +import os import datetime import hashlib import re +import tempfile +from contextlib import contextmanager from szurubooru.errors import ValidationError +@contextmanager +def create_temp_file(**kwargs): + (handle, path) = tempfile.mkstemp(**kwargs) + os.close(handle) + try: + with open(path, 'r+b') as handle: + yield handle + finally: + os.remove(path) + def unalias_dict(input_dict): output_dict = {} for key_list, value in input_dict.items():