def get_thumbnail(self, file_, geometry_string, **options):
logger.debug('<STR_LIT>', file_, geometry_string)<EOL>if file_:<EOL><INDENT>source = ImageFile(file_)<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if settings.THUMBNAIL_PRESERVE_FORMAT:<EOL><INDENT>options.setdefault('<STR_LIT>', self._get_format(source))<EOL><DEDENT>for key, value in self.default_options.items():<EOL><INDENT>options.setdefault(key, value)<EOL><DEDENT>for key, attr in self.extra_options:<EOL><INDENT>value = getattr(settings, attr)<EOL>if value != getattr(default_settings, attr):<EOL><INDENT>options.setdefault(key, value)<EOL><DEDENT><DEDENT>name = self._get_thumbnail_filename(source, geometry_string, options)<EOL>thumbnail = ImageFile(name, default.storage)<EOL>cached = default.kvstore.get(thumbnail)<EOL>if cached:<EOL><INDENT>return cached<EOL><DEDENT>if settings.THUMBNAIL_FORCE_OVERWRITE or not thumbnail.exists():<EOL><INDENT>try:<EOL><INDENT>source_image = default.engine.get_image(source)<EOL><DEDENT>except IOError as e:<EOL><INDENT>logger.exception(e)<EOL>if settings.THUMBNAIL_DUMMY:<EOL><INDENT>return DummyImageFile(geometry_string)<EOL><DEDENT>else:<EOL><INDENT>logger.warning(<EOL>'<STR_LIT>',<EOL>file_, geometry_string,<EOL>)<EOL>return thumbnail<EOL><DEDENT><DEDENT>image_info = default.engine.get_image_info(source_image)<EOL>options['<STR_LIT>'] = image_info<EOL>size = default.engine.get_image_size(source_image)<EOL>source.set_size(size)<EOL>try:<EOL><INDENT>self._create_thumbnail(source_image, geometry_string, options,<EOL>thumbnail)<EOL>self._create_alternative_resolutions(source_image, geometry_string,<EOL>options, thumbnail.name)<EOL><DEDENT>finally:<EOL><INDENT>default.engine.cleanup(source_image)<EOL><DEDENT><DEDENT>default.kvstore.get_or_set(source)<EOL>default.kvstore.set(thumbnail, source)<EOL>return thumbnail<EOL>
Returns thumbnail as an ImageFile instance for file with geometry and
options given. First it will try to get it from the key value store,
secondly it will create it.