def _get_thumbnail_filename(self, source, geometry_string, options): """Computes the destination filename. Overridden to generate the same filename as generated with 'django.core.files.storage.FileSystemStorage' backend, irrespective of what the current storage back-end is. """ source_key = tokey(source.name, 'django.core.files.storage.FileSystemStorage') key = tokey(source_key, geometry_string, serialize(options)) path = '%s/%s/%s' % (key[:2], key[2:4], key) return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path, EXTENSIONS[options['format']])
def _get_thumbnail_filename(self, source, geometry_string, options):###customization """ Computes the destination filename. """ try: root_path = source.storage.path('') except: #some storage backends do not support path() root_path = '' split_path = re.sub(r'^%s%s?' % (root_path, os.sep), '', source.name).split(os.sep) split_path.insert(-1, geometry_string) #make some subdirs to avoid putting too many files in a single dir. key = tokey(source.key, geometry_string, serialize(options)) split_path.insert(-1, key[:2]) split_path.insert(-1, key[2:4]) #attempt to slugify the filename to make it SEO-friendly split_name = split_path[-1].split('.') try: split_path[-1] = '%s.%s' % (slugify('.'.join(split_name[:-1])), split_name[-1]) except: #on fail keep the original filename pass path = os.sep.join(split_path) #if the path already starts with THUMBNAIL_PREFIX do not concatenate the PREFIX #this way we avoid ending up with a url like /images/images/120x120/my.png if not path.startswith(settings.THUMBNAIL_PREFIX): return '%s%s' % (settings.THUMBNAIL_PREFIX, path) return path
def _get_thumbnail_filename(self, source, geometry_string, options): """ Computes the destination filename. """ key = tokey(source.key, geometry_string, serialize(options)) # make some subdirs path = "%s/%s/%s" % (key[:2], key[2:4], key) return "%s%s.%s" % (settings.THUMBNAIL_PREFIX, path, self.extensions[options["format"]])
def _get_thumbnail_filename(self, source, geometry_string, options): """ Computes the destination filename. """ key = tokey(source.key, geometry_string, serialize(options)) # make some subdirs path = '%s/%s/%s' % (key[:2], key[2:4], key) return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path, EXTENSIONS[options['format']])
def _get_thumbnail_filename(self, source, geometry_string, options): """ Computes the destination filename. """ key = tokey(serialize(options)) image_path = os.path.relpath(source.url, source.storage.location) path = '%s-%s-%s' % (os.path.splitext(image_path)[0], geometry_string, key) return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path, EXTENSIONS[options['format']])
def _get_thumbnail_filename(self, source, geometry_string, options): """ Computes the destination filename. """ key = tokey(source.key, geometry_string, serialize(options)) filename, _ext = os.path.splitext(os.path.basename(source.name)) path = '%s/%s' % (key, filename) return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path, EXTENSIONS[options['format']])
def _get_thumbnail_filename(self, source, geometry_string, options): """Computes the destination filename.""" key = tokey(source.key, geometry_string, serialize(options)) filename, _ext = os.path.splitext(os.path.basename(source.name)) path = '{0}/{1}'.format(key, filename) image_format = options['format'] return '{0}{1}.{2}'.format(settings.THUMBNAIL_PREFIX, path, EXTENSIONS[image_format])
def _get_thumbnail_filename(self, source, geometry_string, options): """ Computes the destination filename. """ # HACK: preserving output format of the image if options.get('format', 'auto') == 'auto': options['format'] = guess_image_format(source.name) key = tokey(source.key, geometry_string, serialize(options)) # make some subdirs path = '%s/%s/%s' % (key[:2], key[2:4], key) return '%s%s.%s' % (settings.THUMBNAIL_PREFIX, path, EXTENSIONS[options['format']])
def _get_thumbnail_filename(self, source, geometry_string, options): """ Computes the destination filename. """ key = tokey(source.key, geometry_string, serialize(options)) filename, _ext = os.path.splitext(os.path.basename(source.name)) cache_path = '{}/{}/{}'.format(key[:2], key[2:4], key) filename = '{prefix}{cache_path}/{filename}.{ext}'.format( prefix=settings.THUMBNAIL_PREFIX, cache_path=cache_path, filename=filename, ext=EXTENSIONS[options['format']], ) return filename
def _get_thumbnail_filename(self, source, geometry_string, options): key = tokey(source.key, geometry_string, serialize(options)) path = '%s/%s/%s' % (key[:2], key[2:4], key) return '%s%s/%s' % (settings.THUMBNAIL_PREFIX, path, basename(source.name))
def key(self): return tokey(self.name, self.serialize_storage())
def _generate_thumbnail_url_cache_key(self, file_, size): source = ImageFile(file_) key = "thumbnail_url_%s" % (tokey(source.key, size)) return key
def create_sorl_key(source, geometry_string, options): return tokey(source.key, geometry_string, serialize(options))
def get_thumbnail(self, file_, geometry_string, **options): """ 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. """ logger.debug('Getting thumbnail for file [%s] at [%s]', file_, geometry_string) source = ImageFile(file_) # preserve image filetype if settings.THUMBNAIL_PRESERVE_FORMAT: options.setdefault('format', self._get_format(source)) for key, value in self.default_options.items(): options.setdefault(key, value) # For the future I think it is better to add options only if they # differ from the default settings as below. This will ensure the same # filenames being generated for new options at default. for key, attr in self.extra_options: value = getattr(settings, attr) if value != getattr(default_settings, attr): options.setdefault(key, value) name = self._get_thumbnail_filename(source, geometry_string, options) thumbnail = ImageFile(name, default.storage, key=tokey(source.key, geometry_string, serialize(options))) cached = default.kvstore.get(thumbnail) if cached: return cached # We have to check exists() because the Storage backend does not # overwrite in some implementations. if settings.THUMBNAIL_FORCE_OVERWRITE or not thumbnail.exists(): try: source_image = default.engine.get_image(source) except IOError as e: logger.exception(e) if settings.THUMBNAIL_DUMMY: return DummyImageFile(geometry_string) else: # if S3Storage says file doesn't exist remotely, don't try to # create it and exit early. # Will return working empty image type; 404'd image logger.warning( 'Remote file [%s] at [%s] does not exist', file_, geometry_string, ) return thumbnail # We might as well set the size since we have the image in memory image_info = default.engine.get_image_info(source_image) options['image_info'] = image_info size = default.engine.get_image_size(source_image) source.set_size(size) try: self._create_thumbnail(source_image, geometry_string, options, thumbnail) self._create_alternative_resolutions(source_image, geometry_string, options, thumbnail.name) finally: default.engine.cleanup(source_image) # If the thumbnail exists we don't create it, the other option is # to delete and write but this could lead to race conditions so I # will just leave that out for now. default.kvstore.get_or_set(source) default.kvstore.set(thumbnail, source) return thumbnail
def key(self): if not hasattr(self, "_key"): self._key = tokey(self.name, self.serialize_storage()) return self._key
def get_minecraft_avatar(minecraft_user, geometry_string, force=True): """ This method uses the sorl-thumbnail cache backend to prevent images from being downloaded every time. It requires an username. """ avatar_file = UploadedFile( file=StringIO(), name='%s/%s.png' % (settings.MEDIA_ROOT, tokey(minecraft_user))) try: # Check if the avatar is cached thumbnail = get_thumbnail( avatar_file, '100x100', quality=100, format='PNG') except IOError: download_thumbnail = True else: is_dummy = not hasattr(thumbnail, 'storage') if not is_dummy and not thumbnail.storage.exists(thumbnail.name): # It seems we have the avatar on cache (kvstore) # but it's not present on the storage download_thumbnail = True # Force remove thumbnail from kvstore sorl_default.kvstore.delete(thumbnail) # Log logger.warning('Avatar cache mismatch: %s (resetting)' % ( minecraft_user,)) else: logger.debug('Avatar fetched from cache: %s' % minecraft_user) download_thumbnail = False if download_thumbnail: logger.debug('Downloading avatar: %s' % minecraft_user) # Otherwise download avatar thumbnail = None try: skin_bin = requests.get( 'http://s3.amazonaws.com/MinecraftSkins/%s.png' % ( minecraft_user ) ).content except ConnectionError: return None try: skin = Image.open(StringIO(skin_bin)).convert('RGBA') except IOError: # Image not found or some permission error with S3 if minecraft_user != 'char': if not force: return None # Return default user avatar return settings.STATIC_URL + settings.DEFAULT_USER_AVATAR else: face = skin.crop((8, 8, 16, 16)) accessories = skin.crop((40, 8, 48, 16)) r, g, b, a = accessories.split() accessories = Image.merge('RGB', (r, g, b)) mask = Image.merge('L', (a,)) face.paste(accessories, (0, 0), mask) avatar = face.resize((135, 135)) avatar.save(avatar_file, 'PNG') avatar_file.seek(0) # Save through sorl backend thumbnail = get_thumbnail(avatar_file, '100x100', quality=100, format='PNG') # Use the cached file return get_thumbnail(thumbnail, geometry_string, quality=100, format='PNG').url
def _get_thumbnail_filename(self, source, geometry_string, options): key = tokey(source.key, geometry_string, serialize(options)) path = '%s/%s/%s' % (key[:2], key[2:4], key) return '%s%s/%s' % ( settings.THUMBNAIL_PREFIX, path, basename(source.name))