From 4ff4510ab781498a29238b9045c67e8b059e5c32 Mon Sep 17 00:00:00 2001 From: "Phyks (Lucas Verney)" Date: Fri, 23 Feb 2018 16:51:22 +0100 Subject: [PATCH 1/2] Prevent Out Of Memory errors with image cache, fix #117 --- flatisfy/filters/cache.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/flatisfy/filters/cache.py b/flatisfy/filters/cache.py index 869fcd4..2bb7b28 100644 --- a/flatisfy/filters/cache.py +++ b/flatisfy/filters/cache.py @@ -5,6 +5,7 @@ Caching function for pictures. from __future__ import absolute_import, print_function, unicode_literals +import collections import hashlib import os import requests @@ -31,7 +32,7 @@ class MemoryCache(object): def __init__(self): self.hits = 0 self.misses = 0 - self.map = {} + self.map = collections.OrderedDict() def get(self, key): """ @@ -99,6 +100,10 @@ class ImageCache(MemoryCache): """ Helper to actually retrieve photos if not already cached. """ + # If two many items in the cache, pop one + if len(self.map.keys()) > self.max_items: + self.map.popitem(last=False) + filepath = os.path.join( self.storage_dir, self.compute_filename(url) @@ -116,7 +121,13 @@ class ImageCache(MemoryCache): return None return image - def __init__(self, storage_dir=None): + def __init__(self, max_items=200, storage_dir=None): + """ + :param max_items: Max number of items in the cache, to prevent Out Of + Memory errors. + :param storage_dir: Directory in which images should be stored. + """ + self.max_items = max_items self.storage_dir = storage_dir if self.storage_dir and not os.path.isdir(self.storage_dir): os.makedirs(self.storage_dir) From 0b89f27a43180687d6e5d608c6150ed0419c898c Mon Sep 17 00:00:00 2001 From: "Phyks (Lucas Verney)" Date: Fri, 23 Feb 2018 16:57:00 +0100 Subject: [PATCH 2/2] Fix a bug with locally serving images, fix issue #118 --- flatisfy/filters/cache.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/flatisfy/filters/cache.py b/flatisfy/filters/cache.py index 2bb7b28..a469faa 100644 --- a/flatisfy/filters/cache.py +++ b/flatisfy/filters/cache.py @@ -104,22 +104,24 @@ class ImageCache(MemoryCache): if len(self.map.keys()) > self.max_items: self.map.popitem(last=False) - filepath = os.path.join( - self.storage_dir, - self.compute_filename(url) - ) - if os.path.isfile(filepath): - image = PIL.Image.open(filepath) - else: - req = requests.get(url) - try: - req.raise_for_status() - image = PIL.Image.open(BytesIO(req.content)) - if self.storage_dir: - image.save(filepath, format=image.format) - except (requests.HTTPError, IOError): - return None - return image + # Try to load from local folder + if self.storage_dir: + filepath = os.path.join( + self.storage_dir, + self.compute_filename(url) + ) + if os.path.isfile(filepath): + return PIL.Image.open(filepath) + # Otherwise, fetch it + req = requests.get(url) + try: + req.raise_for_status() + image = PIL.Image.open(BytesIO(req.content)) + if self.storage_dir: + image.save(filepath, format=image.format) + return image + except (requests.HTTPError, IOError): + return None def __init__(self, max_items=200, storage_dir=None): """