111 lines
2.9 KiB
Python
111 lines
2.9 KiB
Python
from papiezator.models import PopeImage, PerfectPope, DECIMAL_PLACES
|
|
from PIL import Image
|
|
from io import BytesIO
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
from papiezator.papiezator_settings import REDIS_TTL, SAGE_REDIS
|
|
try:
|
|
from redis import Redis
|
|
from redis.exceptions import ConnectionError as RedisConnectionError
|
|
redis = Redis()
|
|
except ImportError:
|
|
redis = None
|
|
|
|
def select_best_pope(aspect_ratio, pope):
|
|
""" (float, pope) -> PopeImage
|
|
|
|
"""
|
|
pp = PerfectPope.objects.filter(aspect_ratio=aspect_ratio, pope=pope)
|
|
if pp:
|
|
return pp[0].image
|
|
# popes below and above this ratio
|
|
lte = PopeImage.objects.filter(aspect_ratio__lte=aspect_ratio, pope=pope).order_by('-aspect_ratio')[0:1]
|
|
gte = PopeImage.objects.filter(aspect_ratio__gte=aspect_ratio, pope=pope).order_by('aspect_ratio')[0:1]
|
|
|
|
if gte and lte:
|
|
lte, gte = lte[0], gte[0]
|
|
|
|
lte_distance = abs(aspect_ratio - lte.aspect_ratio)
|
|
gte_distance = abs(aspect_ratio - gte.aspect_ratio)
|
|
|
|
if lte_distance >= gte_distance:
|
|
return_image_path = gte
|
|
else:
|
|
return_image_path = lte
|
|
|
|
# if there are no popes above or below this ratio
|
|
elif gte:
|
|
return_image_path = gte[0]
|
|
elif lte:
|
|
return_image_path = lte[0]
|
|
# or even if there are no popes at all :c
|
|
else:
|
|
return None
|
|
|
|
return habemus_papam(aspect_ratio, image_path=return_image_path, pope=pope)
|
|
|
|
|
|
def habemus_papam(aspect_ratio, image_path, pope):
|
|
pp = PerfectPope(aspect_ratio=aspect_ratio, image=image_path, pope=pope)
|
|
pp.save()
|
|
return image_path
|
|
|
|
|
|
def unpopable(width, height):
|
|
if width == 0 or height == 0:
|
|
return True
|
|
if (width+height) >= 9001:
|
|
return True
|
|
return False
|
|
|
|
|
|
|
|
|
|
def read_pope_from_fs(width, height, pope_image):
|
|
im = Image.open(pope_image.path)
|
|
im = im.resize((width, height))
|
|
f = BytesIO() # FIXME: ceriously.
|
|
im.save(f, "jpeg")
|
|
f.seek(0)
|
|
return f.read()
|
|
|
|
def read_pope(width, height, pope_image):
|
|
""" (int, int, Pope) -> bytes
|
|
get pope and scale for display
|
|
"""
|
|
if redis and not SAGE_REDIS:
|
|
try:
|
|
|
|
key = (width,height, pope_image)
|
|
im = redis.get(key)
|
|
if not im:
|
|
im = read_pope_from_fs(width, height, pope_image)
|
|
redis.set(key, im)
|
|
redis.expire(key, REDIS_TTL)
|
|
|
|
except RedisConnectionError:
|
|
im = read_pope_from_fs(width, height, pope_image)
|
|
else: #TODO: join those two
|
|
im = read_pope_from_fs(width, height, pope_image)
|
|
|
|
|
|
|
|
return im
|
|
|
|
|
|
|
|
|
|
def parse_pope(path):
|
|
im = Image.open(path)
|
|
width, height = im.size
|
|
aspect_ratio = round(width/height, DECIMAL_PLACES)
|
|
return PopeImage(path=path, width=width, height=height, aspect_ratio=aspect_ratio)
|
|
|
|
|
|
def pope_or_death(p, **kwargs):
|
|
try:
|
|
x = p.objects.get(**kwargs)
|
|
except ObjectDoesNotExist:
|
|
x = None
|
|
return x
|
|
|