<s> from io import BytesIO <EOL> from PIL import Image <EOL> import re <EOL> from subprocess import Popen , PIPE <EOL> from thumbor . engines . pil import Engine as PILEngine <EOL> from thumbor . utils import logger <EOL> GIFSICLE_SIZE_REGEX = re . compile ( r'<STR_LIT>' ) <EOL> GIFSICLE_IMAGE_COUNT_REGEX = re . compile ( r'<STR_LIT>' ) <EOL> class Engine ( PILEngine ) : <EOL> @ property <EOL> def size ( self ) : <EOL> return self . image_size <EOL> def run_gifsicle ( self , command ) : <EOL> p = Popen ( [ self . context . server . gifsicle_path ] + command . split ( '<STR_LIT:U+0020>' ) , stdout = PIPE , stdin = PIPE , stderr = PIPE ) <EOL> stdout_data = p . communicate ( input = self . buffer ) [ <NUM_LIT:0> ] <EOL> return stdout_data <EOL> def is_multiple ( self ) : <EOL> return self . frame_count > <NUM_LIT:1> <EOL> def update_image_info ( self ) : <EOL> self . _is_multiple = False <EOL> result = self . run_gifsicle ( '<STR_LIT>' ) <EOL> size = GIFSICLE_SIZE_REGEX . search ( result ) <EOL> self . image_size = size . groups ( ) [ <NUM_LIT:0> ] . split ( '<STR_LIT:x>' ) <EOL> self . image_size [ <NUM_LIT:0> ] , self . image_size [ <NUM_LIT:1> ] = int ( self . image_size [ <NUM_LIT:0> ] ) , int ( self . image_size [ <NUM_LIT:1> ] ) <EOL> count = GIFSICLE_IMAGE_COUNT_REGEX . search ( result ) <EOL> self . frame_count = int ( count . groups ( ) [ <NUM_LIT:0> ] ) <EOL> def load ( self , buffer , extension ) : <EOL> self . extension = extension <EOL> self . buffer = buffer <EOL> self . image = '<STR_LIT>' <EOL> self . operations = [ ] <EOL> self . update_image_info ( ) <EOL> def draw_rectangle ( self , x , y , width , height ) : <EOL> raise NotImplementedError ( ) <EOL> def resize ( self , width , height ) : <EOL> if width == <NUM_LIT:0> and height == <NUM_LIT:0> : <EOL> return <EOL> if width > <NUM_LIT:0> and height == <NUM_LIT:0> : <EOL> arguments = "<STR_LIT>" % width <EOL> elif height > <NUM_LIT:0> and width == <NUM_LIT:0> : <EOL> arguments = "<STR_LIT>" % height <EOL> else : <EOL> arguments = "<STR_LIT>" % ( width , height ) <EOL> self . operations . append ( arguments ) <EOL> def crop ( self , left , top , right , bottom ) : <EOL> arguments = "<STR_LIT>" % ( left , top , right , bottom ) <EOL> self . operations . append ( arguments ) <EOL> self . flush_operations ( ) <EOL> self . update_image_info ( ) <EOL> def rotate ( self , degrees ) : <EOL> if degrees not in [ <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ] : <EOL> return <EOL> arguments = '<STR_LIT>' % degrees <EOL> self . operations . append ( arguments ) <EOL> def flip_vertically ( self ) : <EOL> self . operations . append ( '<STR_LIT>' ) <EOL> def flip_horizontally ( self ) : <EOL> self . operations . append ( '<STR_LIT>' ) <EOL> def extract_cover ( self ) : <EOL> arguments = '<STR_LIT>' <EOL> self . operations . append ( arguments ) <EOL> self . flush_operations ( ) <EOL> self . update_image_info ( ) <EOL> def flush_operations ( self ) : <EOL> if not self . operations : <EOL> return <EOL> self . buffer = self . run_gifsicle ( "<STR_LIT:U+0020>" . join ( self . operations ) ) <EOL> self . operations = [ ] <EOL> def read ( self , extension = None , quality = None ) : <EOL> self . flush_operations ( ) <EOL> try : <EOL> with Image . open ( BytesIO ( self . buffer ) ) as image : <EOL> image . verify ( ) <EOL> except Exception : <EOL> self . context . metrics . incr ( '<STR_LIT>' ) <EOL> logger . error ( "<STR_LIT>" . format ( <EOL> url = self . context . request . url <EOL> ) ) <EOL> raise <EOL> return self . buffer <EOL> def convert_to_grayscale ( self ) : <EOL> self . operations . append ( '<STR_LIT>' ) </s>
