Merge branch 'oom' into 'master'
Prevent Out Of Memory errors with image cache, fix #118 Closes #118 and #117 See merge request phyks/Flatisfy!26
This commit is contained in:
commit
3855888bcb
@ -5,6 +5,7 @@ Caching function for pictures.
|
|||||||
|
|
||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
|
import collections
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
@ -31,7 +32,7 @@ class MemoryCache(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.hits = 0
|
self.hits = 0
|
||||||
self.misses = 0
|
self.misses = 0
|
||||||
self.map = {}
|
self.map = collections.OrderedDict()
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key):
|
||||||
"""
|
"""
|
||||||
@ -99,24 +100,36 @@ class ImageCache(MemoryCache):
|
|||||||
"""
|
"""
|
||||||
Helper to actually retrieve photos if not already cached.
|
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)
|
||||||
|
|
||||||
|
# Try to load from local folder
|
||||||
|
if self.storage_dir:
|
||||||
filepath = os.path.join(
|
filepath = os.path.join(
|
||||||
self.storage_dir,
|
self.storage_dir,
|
||||||
self.compute_filename(url)
|
self.compute_filename(url)
|
||||||
)
|
)
|
||||||
if os.path.isfile(filepath):
|
if os.path.isfile(filepath):
|
||||||
image = PIL.Image.open(filepath)
|
return PIL.Image.open(filepath)
|
||||||
else:
|
# Otherwise, fetch it
|
||||||
req = requests.get(url)
|
req = requests.get(url)
|
||||||
try:
|
try:
|
||||||
req.raise_for_status()
|
req.raise_for_status()
|
||||||
image = PIL.Image.open(BytesIO(req.content))
|
image = PIL.Image.open(BytesIO(req.content))
|
||||||
if self.storage_dir:
|
if self.storage_dir:
|
||||||
image.save(filepath, format=image.format)
|
image.save(filepath, format=image.format)
|
||||||
|
return image
|
||||||
except (requests.HTTPError, IOError):
|
except (requests.HTTPError, IOError):
|
||||||
return None
|
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
|
self.storage_dir = storage_dir
|
||||||
if self.storage_dir and not os.path.isdir(self.storage_dir):
|
if self.storage_dir and not os.path.isdir(self.storage_dir):
|
||||||
os.makedirs(self.storage_dir)
|
os.makedirs(self.storage_dir)
|
||||||
|
Loading…
Reference in New Issue
Block a user